This content is hosted by Algolia, but not associated with it.
Logo image
208 results
  • Web-Dev-Hub
    I am a musician, electrical engineer & web developer Please note that this website is in development and is often broken! Contact A Quick Guide To Big O Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of calculating time complexity? Get Started Python Guide Python has a built in help function that let's you see a description of the source code without having to navigate to it… “-SickNasty … Autor Unknown” . View Posts Guitar Effects Triggering w DTW Learn More Beginner Guide React As I learn to build web applications in React I will blog about it in this series in an attempt to capture the questions that a complete beginner might encounter that a more seasoned developer would take for granted! Scope & Closure Scope & Context in JS The scope of a program in JavaScript is the set of variables that are available for use within the program. Web Audio Daw PostgreSQL Cheat Sheet, Everything You Need to Get Started With VSCode Extensions & Resources, Super Simple Intro To HTML, Understanding Git... etc.... Current Interests From github repositories to existential questions. Angolia Full Text Search Full Text Search Convolutional Neural Networks Artificial neural networks, usually simply called neural networks, are computing systems vaguely inspired by the biological neural networks Jamstack Why Jamstack Jamstack is the new standard architecture for the web. Using Git workflows and modern build tools, pre-rendered content is served to a CDN and made dynamic through APIs and serverless functions. Technologies in the stack include JavaScript frameworks, Static Site Generators, Headless CMSs, and CDNs. Asynchronous JavaScript The term asynchronous refers to two or more objects or events not existing or happening at the same time (or multiple related things happening without waiting for the previous one to complete). In computing, the word "asynchronous" is used in two major contexts. NJ Devils New Jersey Devils Hockey Team(Hockey in general) Team identity The old green style jerseys used from 1982 to 1992The jerseys used from 1992 to 2017 Sean Avery of the New York Rangers attempts to distract Brodeur during the 2008 Stanley Cup playoffs. The playoff series was the fifth to feature the Devils–Rangers rivalry. lorem-ipsum ITER Fusion Reactor Experiment (Southern France) Break Even Nuclear Fusion Candidate In December, researchers at the Joint European Torus (JET) started conducting fusion experiments with tritium — a rare and radioactive isotope of hydrogen. The facility is a one-tenth-volume mock-up of the US$22-billion ITER project and has the same doughnut-shaped 'tokamak' design — the world's most developed approach to fusion energy. It is the first time since 1997 that researchers have done experiments in a tokamak with any significant amount of tritium. Resume & Portfolio Resume Learn More Download PDF Showcase My Projects! Learn More Blog-Archive-And-Mini-Projects src=" https://random-static-html-deploys.netlify.app/showcase2.html" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen> Web Audio DAW Go To Web Audio Daw Quick Links quick links home About Web-Dev-Hub is my personal blogand documentation site Learn More Articles resources Learn More Audio Audio Projects Learn More Career Reference materials and descriptions of fundamental concepts as well as visua Learn More Community We'd love it if you participate in the Libris community. Find out how to get connected. Learn More Content In this section you'll learn how to add syntax highlighting, examples, callouts and much more. Learn More Data Structures In this section you'll learn how to add syntax highlighting, examples, callouts and much more. Learn More Docs Documentation Learn More FAQ In this section you'll find commonly asked questions regarding the Libris theme. If you have questions, don't hesitate to ask us directly. Learn More Interactive feel free to try the examples Learn More Javascript Javascript articles and docs Learn More Interviewing These are some of my active projects. Learn More Leetcode feel free to try the examples Learn More Projects We'd love it if you participate in the Web-Dev-Hubcommunity. Find out how to get connected. Learn More Python Python Learn More QuickRef In this section you'll find basic information about Web-Dev-Hub and how to use it. Learn More React To make it easy to write documentation in plain Markdown, most React are styled using Markdown elements with few additional CSS classes. Learn More Reference helpful reference guides Learn More Tools See some interesting tools developed by the Web-Dev-Hubcommunity to help automate parts of your workflow. Learn More Tutorials Walkthroughs of various development activities and skills Learn More Contact get in touch! +1 (551) - 254 - 5505 Contact email Collaborate Subscribe (Youtube)
    https://bgoonz-blog.netlify.app/images/code.png
  • Showcase
    Showcase Some of my more engaging projects! Git HTML PREVIEW Preview html files by pasting their url into the search bar Access-Control-Allow-Origin Header When Site A tries to fetch content from Site B Live Site Guitar Effects Automation Using Subsequence Dynamic Time Warping Modified subsequence dynamic time warping feature detection using pure data implemented in python Slide Show Data Structures Interactive Learning Hub Big O notation is the language we use for talking about how long an algorithm takes to run. It's how we compare the efficiency of different approaches to a problem. Live Site Learning Redux React Redux provides a pair of custom React hooks that allow your React components to interact with the Redux store. Website Mihir-Beg-Music.com Artist Showcase & Podcasting Site Live Site Aux Blog w NextJS Here lives my alternate/backup blog site! git repo Potluck Planner Potluck Planner If you have ever tried to organize a potluck through text messages, online to-do lists or spreadsheets, you'll understand why this app is essential.In the world of social gatherings and potlucks the "Potluck Planner" is king. This is your place for all things pot luck. Zumzi Video Conferencing Features: Live Streaming, Screen Sharing, Fine control over all video & audio parameters and user permissions, Supports video streaming at various resolutions: Standard, HD, FHD and 4K, Group Chat, One-to-One chat, Invite Participants Live Site Web Audio Workstation Made using jQuery and Vanilla JS Go To Live Site Github Repo
    https://bgoonz-blog.netlify.app/images/My Post-4ecb169f.png
  • Web-Dev-Hub
    Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'),
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'), s.languages.insertBefore('inside','attr-value',{'style-attr': { pattern: /\s
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    README for this website Hi 👋, I'm Bryan WEBSITE Search Website: search Backup Repo Deploy Github pages Homepage Technologies used: Global Site Tag Global Site Tag Usage Statistics - Download List of All Websites using Global Site Tag Google's primary tag for Google Measurement/Conversion Tracking, Adwords and DoubleClick. Google Analytics Google Analytics Usage Statistics - Download List of All Websites using Google Analytics Google Analytics offers a host of compelling features and benefits for everyone from senior executives and advertising and marketing professionals to site owners and content developers. Application Performance - Audience Measurement - Visitor Count Tracking Google Analytics 4 Google Analytics 4 Usage Statistics - Download List of All Websites using Google Analytics 4 Google Analytics 4 formerly known as App + Web is a new version of Google Analytics that was released in October 2020. Widgets View Global Trends Imgur Imgur Usage Statistics - Download List of All Websites using Imgur The page contains content from image sharing website imgur. Google Font API Google Font API Usage Statistics - Download List of All Websites using Google Font API The Google Font API helps you add web fonts to any web page. Fonts Google Tag Manager Google Tag Manager Usage Statistics - Download List of All Websites using Google Tag Manager Tag management that lets you add and update website tags without changes to underlying website code. Tag Management Icons8 Icons8 Usage Statistics - Download List of All Websites using Icons8 Icons, photos and illustrations. Image Provider Lorem Ipsum Lorem Ipsum Usage Statistics - Download List of All Websites using Lorem Ipsum This website contains the phrase 'lorem ipsum' which means it may have placeholder text. AddThis AddThis Usage Statistics - Download List of All Websites using AddThis Widgets that allow visitors to save and promote the site. Social Sharing - Bookmarking tawk.to tawk.to Usage Statistics - Download List of All Websites using tawk.to tawk.to is a free live chat app that lets you monitor and chat with visitors. Live Chat Frameworks View Global Trends Gatsby JS Gatsby JS Usage Statistics - Download List of All Websites using Gatsby JS Modern website and web apps generator for React. Mobile View Global Trends Viewport Meta Viewport Meta Usage Statistics - Download List of All Websites using Viewport Meta This page uses the viewport meta tag which means the content may be optimized for mobile content. IPhone / Mobile Compatible IPhone / Mobile Compatible Usage Statistics - Download List of All Websites using IPhone / Mobile Compatible The website contains code that allows the page to support IPhone / Mobile Content. Apple Mobile Web Clips Icon Apple Mobile Web Clips Icon Usage Statistics - Download List of All Websites using Apple Mobile Web Clips Icon This page contains an icon for iPhone, iPad and iTouch devices. Content Delivery Network View Global Trends AJAX Libraries API AJAX Libraries API Usage Statistics - Download List of All Websites using AJAX Libraries API The AJAX Libraries API is a content distribution network and loading architecture for the most popular, open source JavaScript libraries. jsDelivr jsDelivr Usage Statistics - Download List of All Websites using jsDelivr A free CDN where Javascript developers can host their files. Encompasses MaxCDN, and BootstrapCDN. CloudFront CloudFront Usage Statistics - Download List of All Websites using CloudFront Amazon CloudFront is a web service for content delivery. It integrates with other Amazon Web Services to give developers and businesses an easy way to distribute content to end users with low latency, high data transfer speeds, and no commitments. Content Management System View Global Trends Netlify Netlify Usage Statistics - Download List of All Websites using Netlify Netlify is a platform that automates your code to create web sites. JavaScript Libraries and Functions View Global Trends Google Hosted Libraries Google Hosted Libraries Usage Statistics - Download List of All Websites using Google Hosted Libraries Google Hosted Libraries is a globally available content distribution network for the most popular, open-source JavaScript libraries. Google Hosted jQuery Google Hosted jQuery Usage Statistics - Download List of All Websites using Google Hosted jQuery jQuery hoted at Google. Advertising View Global Trends Google Adsense Google Adsense Usage Statistics - Download List of All Websites using Google Adsense A contextual advertising solution for delivering Google AdWords ads that are relevant to site content pages. Contextual Advertising Google Adsense Asynchronous Google Adsense Asynchronous Usage Statistics - Download List of All Websites using Google Adsense Asynchronous Fully asynchronous version of the AdSense ad code. Document Encoding View Global Trends UTF-8 UTF-8 Usage Statistics - Download List of All Websites using UTF-8 UTF-8 (8-bit UCS/Unicode Transformation Format) is a variable-length character encoding for Unicode. It is the preferred encoding for web pages. Document Standards View Global Trends HTML5 DocType HTML5 DocType Usage Statistics - Download List of All Websites using HTML5 DocType The DOCTYPE is a required preamble for HTML5 websites. Cascading Style Sheets Cascading Style Sheets Usage Statistics - Download List of All Websites using Cascading Style Sheets Cascading Style Sheets (CSS) is a stylesheet language used to describe the presentation of a document written in a markup language. Its most common application is to style web pages written in HTML Open Graph Protocol Open Graph Protocol Usage Statistics - Download List of All Websites using Open Graph Protocol The Open Graph protocol enables any web page to become a rich object in a social graph, a open protocol supported by Facebook Twitter Cards Twitter Cards Usage Statistics - Download List of All Websites using Twitter Cards Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Javascript Javascript Usage Statistics - Download List of All Websites using Javascript JavaScript is a scripting language most often used for client-side web development. IFrame IFrame Usage Statistics - Download List of All Websites using IFrame The page shows content with an iframe; an embedded frame that loads another webpage. Font Face Rule Font Face Rule Usage Statistics - Download List of All Websites using Font Face Rule The @font-face rule allows for linking to fonts that are automatically activated when needed. X-UA-Compatible X-UA-Compatible Usage Statistics - Download List of All Websites using X-UA-Compatible Allows a website to define how a page is rendered in Internet Explorer 8, allowing a website to decide to use IE7 style rendering over IE8 rendering. Meta Keywords Meta Keywords Usage Statistics - Download List of All Websites using Meta Keywords Meta tag containing keywords related to the page. Meta Description Meta Description Usage Statistics - Download List of All Websites using Meta Description The description attribute provides a concise explanation of the page content. HTML 5 Specific Tags HTML 5 Specific Tags Usage Statistics - Download List of All Websites using HTML 5 Specific Tags This page contains tags that are specific to an HTML 5 implementation. WAI-ARIA WAI-ARIA Usage Statistics - Download List of All Websites using WAI-ARIA A way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. Strict Transport Security Strict Transport Security Usage Statistics - Download List of All Websites using Strict Transport Security The HTTP Strict-Transport-Security (HSTS) header instructs the browser to only use https. HSTS HSTS Usage Statistics - Download List of All Websites using HSTS Forces browsers to only communicate with the site using HTTPS. HSTS IncludeSubdomains PreLoad HSTS IncludeSubdomains PreLoad Usage Statistics - Download List of All Websites using HSTS IncludeSubdomains PreLoad This website includes instructions for HSTS loading that would allow it to be submitted to the HSTS preload list. Web Master Registration View Global Trends Google Webmaster Google Webmaster Usage Statistics - Download List of All Websites using Google Webmaster Webmaster tools provide you with a free and easy way to make your site more Google-friendly. Content Delivery Network View Global Trends Content Delivery Network Content Delivery Network Usage Statistics - Download List of All Websites using Content Delivery Network This page contains links that give the impression that some of the site contents are stored on a content delivery network. Docs Structure:. ├── ./About │ ├── ./About/index.md │ ├── ./About/introduction2bg.md │ ├── ./About/me.md │ └── ./About/resume.md ├── ./articles │ ├── ./articles/algo.md │ └── ./articles/basic-web-dev.md ├── ./faq │ ├── ./faq/Contact.md │ ├── ./faq/index.md │ └── ./faq/other-sites.md ├── ./index.md ├── ./jupyter-notebooks.md ├── ./links │ ├── ./links/Social.md │ ├── ./links/index.md │ └── ./links/my-websites.md ├── ./portfolio-web.md ├── ./python.md ├── ./quick-reference │ ├── ./quick-reference/Emmet.md │ ├── ./quick-reference/index.md │ ├── ./quick-reference/installation.md │ └── ./quick-reference/new-repo-instructions.md ├── ./react │ ├── ./react/createReactApp.md │ ├── ./react/index.md │ └── ./react/react2.md ├── ./resources.md └── ./tools ├── ./tools/Git-Html-Preview.md ├── ./tools/default-readme.md ├── ./tools/index.md ├── ./tools/notes-template.md └── ./tools/plug-ins.md 7 directories, 29 files Sitemap:/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Sitemap:/blog/big-o-complexity//showcase//blog/blog-archive//blog//review//blog/data-structures//blog/blogwcomments//blog/platform-docs//blog/python-resources//blog/python-for-js-dev//docs/gallery//blog/my-medium//docs/search//docs/about/eng-portfolio//docs/about/intrests//docs/sitemap//docs/about/resume//blog/web-scraping//docs/about/job-search//docs//docs/articles/buffers//docs/about//docs/articles/event-loop//docs/articles/dev-dep//docs/articles//docs/articles/install//docs/articles/fs-module//docs/articles/node-cli-args//docs/articles/module-exports//docs/articles/node-env-variables//docs/articles/intro//docs/articles/node-js-language//docs/articles/basic-web-dev//docs/articles/node-repl//docs/articles/node-package-manager//docs/articles/node-run-cli//docs/articles/npx//docs/articles/v8//docs/articles/nodevsbrowser//docs/articles/reading-files//docs/articles/nodejs//docs/articles/npm//docs/articles/semantic//docs/articles/writing-files//docs/audio/dynamic-time-warping//docs/audio//docs/audio/terms//docs/articles/os-module//docs/community//docs/community/video-chat//docs/content/archive//docs/content/data-structures-algo//docs/content//docs/content/notes-template//docs/content/gatsby-Queries-Mutations//docs/content/projects//docs/content/trouble-shooting//docs/audio/dfft//docs/content/algo//docs/docs/await-keyword//docs/docs/appendix//docs/docs/algolia//docs/docs/data-structures-docs//docs/docs//docs/docs/git-repos//docs/docs/sitemap//docs/docs/css//docs/docs/regex-in-js//docs/faq/contact//docs/interact/jupyter-notebooks//docs/interact/clock//docs/interact//docs/faq//docs/interact/video-chat//docs/interact/other-sites//docs/faq/plug-ins//docs/medium/my-websites//docs/medium/medium-links//docs/medium//docs/quick-reference/create-react-app//docs/javascript/constructor-functions//docs/quick-reference/Emmet//docs/python//docs/quick-reference/awesome-static//docs/quick-reference//docs/quick-reference/new-repo-instructions//docs/quick-reference/installation//docs/quick-reference/google-firebase//docs/quick-reference/notes-template//docs/quick-reference/heroku-error-codes//docs/quick-reference/psql-setup//docs/react/createReactApp//docs/quick-reference/topRepos//docs/react/react2//docs/quick-reference/resources//docs/quick-reference/vscode//docs/tools/dev-utilities//docs/tools/data-structures//docs/tools/markdown-html//docs/quick-reference/psql/ Links: Try it out without cloning the entire repo: stackblitz demo hosted on firebase/showcase//repos//blog//docs/jupyter-notebooks//docs/portfolio-web//docs/python//docs/About//docs/About/resume//docs/about//docs/faq//docs/quick-reference//docs/quick-reference/Emmet//docs/quick-reference/new-repo-instructions//docs/links/Social//docs/links//docs/quick-reference/installation//docs/links/my-websites//docs//blog/community//blog/python//docs/resources//docs/react/createReactApp//docs/tools//notes-template//blog/my-medium//docs/tools/default-readme//docs/tools/plug-ins//docs/react/react2//docs/tools/notes-template//review//docs/articles/basic-web-dev//blog/data-structures//docs/About/me//docs/About/introduction2bg//docs/react//docs/tools/Git-Html-Preview//gallery/ Blog introductory-react-part-2 a-very-quick-guide-to-calculating-big-o-computational-complexity introduction-to-react-for-complete-beginners scheduling-settimeout-and-setinterval css-animations these-are-the-bash-shell-commands-that-stand-between-me-and-insanity how-to-implement-native-es6-data-structures-using-arrays-objects objects-in-javascript absolute-beginners-guide-to-javascript-part1 web-developer-resource-list-part-4 vscode-extensions-specifically-for-javascript-development a-list-of-all-of-my-articles-to-link-to-future-posts lists-stacks-and-queues-in-javascript web-development-resources-part-3 web-development-interview-part-3 running-list-of-interesting-articles-tools the-best-cloud-based-code-playgrounds-of-2021-part-1 front-end-interview-questions-part-2 web-developer-resource-list-part-2 http-basics javascript-frameworks-libraries my-take-on-awesome-javascript get-started-with-vscode-extensions my-favorite-vscode-themes object-oriented-programming-in-javascript javascript-rotate-array-problemwalkthrough super-simple-intro-to-html-651d695f9bc everything-you-need-to-know-about-relational-databases-sql-postgresql understanding-git-a-beginners-guide-containing-cheat-sheets-resources-b50c9c01a107 complete-javascript-reference-guide-64306cd6b0db- [🚀 Quick start Create a Gatsby site. Use the Gatsby CLI to create a new site, specifying the default starter.# create a new Gatsby site using the default starter gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default Start developing. Navigate into your new site's directory and start it up. cd my-default-starter/ gatsby develop Open the source code and start editing! Your site is now running at http://localhost:8000! _Note: You'll also see a second link: _ http://localhost:8000/___graphql. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the Gatsby tutorial. Open the my-default-starter directory in your code editor of choice and edit src/pages/index.js. Save your changes and the browser will update in real time!🧐 What's inside? A quick look at the top-level files and directories you'll see in a Gatsby project.. ├── node_modules ├── src ├── .gitignore ├── .prettierrc ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── LICENSE ├── package-lock.json ├── package.json └── README.md /node_modules: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed./src: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. src is a convention for “source code”..gitignore: This file tells git which files it should not track / not maintain a version history for..prettierrc: This is a configuration file for Prettier. Prettier is a tool to help keep the formatting of your code consistent. gatsby-browser.js: This file is where Gatsby expects to find any usage of the Gatsby browser APIs (if any). These allow customization/extension of default Gatsby settings affecting the browser. gatsby-config.js: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you'd like to include, etc. (Check out the config docs for more detail). gatsby-node.js: This file is where Gatsby expects to find any usage of the Gatsby Node APIs (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process. gatsby-ssr.js: This file is where Gatsby expects to find any usage of the Gatsby server-side rendering APIs (if any). These allow customization of default Gatsby settings affecting server-side rendering. LICENSE: This Gatsby starter is licensed under the 0BSD license. This means that you can see this file as a placeholder and replace it with your own license. package-lock.json (See package.json below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. (You won't change this file directly). package.json: A manifest file for Node.js projects, which includes things like metadata (the project's name, author, etc). This manifest is how npm knows which packages to install for your project. README.md: A text file containing useful reference information about your project.🎓 Learning Gatsby Looking for more guidance? Full documentation for Gatsby lives on the website. Here are some places to start: For most developers, we recommend starting with our in-depth tutorial for creating a site with Gatsby. It starts with zero assumptions about your level of ability and walks through every step of the process. To dive straight into code samples, head to our documentation. In particular, check out the Guides, API Reference, and Advanced Tutorials sections in the sidebar.💫 Deploy Codebase: bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ tree -f . ├── ./components │ ├── ./components/ActionLink.js │ ├── ./components/CtaButtons.js │ ├── ./components/DocsMenu.js │ ├── ./components/DocsSubmenu.js │ ├── ./components/Footer.js │ ├── ./components/Header.js │ ├── ./components/Icon.js │ ├── ./components/Layout.js │ ├── ./components/SectionContent.js │ ├── ./components/SectionCta.js │ ├── ./components/SectionDocs.js │ ├── ./components/SectionGrid.js │ ├── ./components/SectionHero.js │ ├── ./components/Submenu.js │ ├── ./components/global.css │ └── ./components/index.js ├── ./data │ └── ./data/doc_sections.yml ├── ./hooks │ └── ./hooks/useScript.js ├── ./html.js ├── ./pages │ ├── ./pages/blog │ │ ├── ./pages/blog/blog-archive.md │ │ ├── ./pages/blog/blogwcomments.md │ │ ├── ./pages/blog/data-structures.md │ │ ├── ./pages/blog/index.md │ │ ├── ./pages/blog/my-medium.md │ │ ├── ./pages/blog/platform-docs.md │ │ ├── ./pages/blog/python-for-js-dev.md │ │ ├── ./pages/blog/python-resources.md │ │ └── ./pages/blog/web-scraping.md │ ├── ./pages/docs │ │ ├── ./pages/docs/about │ │ │ ├── ./pages/docs/about/index.md │ │ │ ├── ./pages/docs/about/me.md │ │ │ ├── ./pages/docs/about/node │ │ │ │ ├── ./pages/docs/about/node/install.md │ │ │ │ ├── ./pages/docs/about/node/intro.md │ │ │ │ ├── ./pages/docs/about/node/nodejs.md │ │ │ │ ├── ./pages/docs/about/node/nodevsbrowser.md │ │ │ │ ├── ./pages/docs/about/node/reading-files.md │ │ │ │ └── ./pages/docs/about/node/writing-files.md │ │ │ ├── ./pages/docs/about/npm.md │ │ │ └── ./pages/docs/about/resume.md │ │ ├── ./pages/docs/articles │ │ │ ├── ./pages/docs/articles/algo.md │ │ │ ├── ./pages/docs/articles/article-compilation.md │ │ │ ├── ./pages/docs/articles/basic-web-dev.md │ │ │ ├── ./pages/docs/articles/gists.md │ │ │ ├── ./pages/docs/articles/index.md │ │ │ ├── ./pages/docs/articles/install.md │ │ │ ├── ./pages/docs/articles/intro.md │ │ │ ├── ./pages/docs/articles/python.md │ │ │ ├── ./pages/docs/articles/reading-files.md │ │ │ ├── ./pages/docs/articles/resources.md │ │ │ ├── ./pages/docs/articles/ten-jamstack-apis-to-checkout.md │ │ │ └── ./pages/docs/articles/writing-files.md │ │ ├── ./pages/docs/docs │ │ │ └── ./pages/docs/docs/tools │ │ │ └── ./pages/docs/docs/tools/file-types.md │ │ ├── ./pages/docs/faq │ │ │ ├── ./pages/docs/faq/contact.md │ │ │ └── ./pages/docs/faq/index.md │ │ ├── ./pages/docs/gists.md │ │ ├── ./pages/docs/index.md │ │ ├── ./pages/docs/interact │ │ │ ├── ./pages/docs/interact/clock.md │ │ │ ├── ./pages/docs/interact/index.md │ │ │ └── ./pages/docs/interact/jupyter-notebooks.md │ │ ├── ./pages/docs/links │ │ │ ├── ./pages/docs/links/index.md │ │ │ ├── ./pages/docs/links/medium-links.md │ │ │ ├── ./pages/docs/links/my-websites.md │ │ │ └── ./pages/docs/links/social.md │ │ ├── ./pages/docs/quick-reference │ │ │ ├── ./pages/docs/quick-reference/Emmet.md │ │ │ ├── ./pages/docs/quick-reference/docs.md │ │ │ ├── ./pages/docs/quick-reference/index.md │ │ │ ├── ./pages/docs/quick-reference/installation.md │ │ │ └── ./pages/docs/quick-reference/new-repo-instructions.md │ │ ├── ./pages/docs/react │ │ │ ├── ./pages/docs/react/createReactApp.md │ │ │ ├── ./pages/docs/react/index.md │ │ │ └── ./pages/docs/react/react2.md │ │ ├── ./pages/docs/react-in-depth.md │ │ ├── ./pages/docs/sitemap.md │ │ └── ./pages/docs/tools │ │ ├── ./pages/docs/tools/index.md │ │ ├── ./pages/docs/tools/notes-template.md │ │ ├── ./pages/docs/tools/plug-ins.md │ │ └── ./pages/docs/tools/vscode.md │ ├── ./pages/index.md │ ├── ./pages/notes-template.md │ ├── ./pages/review.md │ └── ./pages/showcase.md ├── ./sass │ ├── ./sass/imports │ │ ├── ./sass/imports/_animations.scss │ │ ├── ./sass/imports/_buttons.scss │ │ ├── ./sass/imports/_docs.scss │ │ ├── ./sass/imports/_footer.scss │ │ ├── ./sass/imports/_forms.scss │ │ ├── ./sass/imports/_functions.scss │ │ ├── ./sass/imports/_general.scss │ │ ├── ./sass/imports/_header.scss │ │ ├── ./sass/imports/_helpers.scss │ │ ├── ./sass/imports/_icons.scss │ │ ├── ./sass/imports/_palettes.scss │ │ ├── ./sass/imports/_posts.scss │ │ ├── ./sass/imports/_prism.scss │ │ ├── ./sass/imports/_reset.scss │ │ ├── ./sass/imports/_sections.scss │ │ ├── ./sass/imports/_structure.scss │ │ ├── ./sass/imports/_tables.scss │ │ └── ./sass/imports/_variables.scss │ └── ./sass/main.scss ├── ./templates │ ├── ./templates/advanced.js │ ├── ./templates/blog.js │ ├── ./templates/docs.js │ ├── ./templates/page.js │ └── ./templates/post.js └── ./utils ├── ./utils/attribute.js ├── ./utils/classNames.js ├── ./utils/cycler.js ├── ./utils/getData.js ├── ./utils/getPage.js ├── ./utils/getPageByFilePath.js ├── ./utils/getPages.js ├── ./utils/htmlToReact.js ├── ./utils/index.js ├── ./utils/link.js ├── ./utils/markdownify.js ├── ./utils/pathJoin.js ├── ./utils/toStyleObj.js ├── ./utils/toUrl.js └── ./utils/withPrefix.js 21 directories, 119 files bryan@LAPTOP-9LGJ3JGS:/c/MY-WEB-DEV/BLOG____2.0/BLOG_2.0/src$ Components Click to see React Components (src folder)! ActionLink! ActionLink import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import Icon from './Icon'; export default class ActionLink extends React.Component { render() { let action = \_.get(this.props, 'action', null); return ( <Link to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '\_blank' } : null)} {...(_.get(action, 'new*window', null) || *.get(action, 'no*follow', null) ? { rel: (*.get(action, 'new*window', null) ? 'noopener ' : '') + (*.get(action, 'no*follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: *.get(action, 'style', null) !== 'link', 'button-secondary': _.get(action, 'style', null) === 'secondary', 'button-icon': _.get(action, 'style', null) === 'icon' })} > {_.get(action, 'style', null) === 'icon' && _.get(action, 'icon*class', null) ? ( <React.Fragment> <Icon {...this.props} icon={*.get(action, 'icon*class', null)} /> <span className="screen-reader-text">{*.get(action, 'label', null)}</span> </React.Fragment> ) : ( \_.get(action, 'label', null) )} </Link> ); } } CtaButtons! CtaButtons import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; export default class CtaButtons extends React.Component { render() { let actions = _.get(this.props, 'actions', null); return _.map(actions, (action, action_idx) => ( <Link key={action_idx} to={withPrefix(_.get(action, 'url', null))} {...(_.get(action, 'new_window', null) ? { target: '_blank' } : null)} {...(_.get(action, 'new_window', null) || _.get(action, 'no_follow', null) ? { rel: (_.get(action, 'new_window', null) ? 'noopener ' : '') + (_.get(action, 'no_follow', null) ? 'nofollow' : '') } : null)} className={classNames({ button: _.get(action, 'style', null) === 'primary' || _.get(action, 'style', null) === 'secondary', 'button-secondary': _.get(action, 'style', null) === 'secondary' })} > {_.get(action, 'label', null)} </Link> )); } } Click to expand! DocsMenu import React from 'react'; import _ from 'lodash'; import { getPage, classNames, Link, withPrefix, pathJoin, getPages } from '../utils'; import DocsSubmenu from './DocsSubmenu'; export default class DocsMenu extends React.Component { render() { let site = _.get(this.props, 'site', null); let page = _.get(this.props, 'page', null); let root_docs_path = _.get(site, 'data.doc_sections.root_docs_path', null); let root_page = getPage(this.props.pageContext.pages, root_docs_path); return ( <nav id="docs-nav" className="docs-nav"> <div id="docs-nav-inside" className="docs-nav-inside sticky"> <button id="docs-nav-toggle" className="docs-nav-toggle"> Navigate Docs <span className="icon-angle-right" aria-hidden="true" /> </button> <div className="docs-nav-menu"> <ul id="docs-menu" className="docs-menu"> <li className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(root_page, 'url', null) })} > <Link to={withPrefix(_.get(root_page, 'url', null))}>{_.get(root_page, 'frontmatter.title', null)}</Link> </li> {_.map(_.get(site, 'data.doc_sections.sections', null), (section, section_idx) => { let section_path = pathJoin(root_docs_path, section); let section_page = getPage(this.props.pageContext.pages, section_path); let child_pages = _.orderBy(getPages(this.props.pageContext.pages, section_path), 'frontmatter.weight'); let child_count = _.size(child_pages); let has_children = child_count > 0 ? true : false; let is_current_page = _.get(page, 'url', null) === _.get(section_page, 'url', null) ? true : false; let is_active = _.get(page, 'url', null).startsWith(_.get(section_page, 'url', null)); return ( <React.Fragment key={section_idx + '.1'}> <li key={section_idx} className={classNames('docs-menu-item', { 'has-children': has_children, current: is_current_page, active: is_active })} > <Link to={withPrefix(_.get(section_page, 'url', null))}>{_.get(section_page, 'frontmatter.title', null)}</Link> {has_children && ( <React.Fragment> <button className="docs-submenu-toggle"> <span className="screen-reader-text">Submenu</span> <span className="icon-angle-right" aria-hidden="true" /> </button> <DocsSubmenu {...this.props} child_pages={child_pages} page={page} site={site} /> </React.Fragment> )} </li> </React.Fragment> ); })} </ul> </div> </div> </nav> ); } } Click to expand! DocsSubmenu import React from 'react'; import _ from 'lodash'; import { classNames, Link, withPrefix } from '../utils'; export default class DocsSubmenu extends React.Component { render() { let child_pages = _.get(this.props, 'child_pages', null); let page = _.get(this.props, 'page', null); return ( <ul className="docs-submenu"> {_.map(child_pages, (child_page, child_page_idx) => ( <li key={child_page_idx} className={classNames('docs-menu-item', { current: _.get(page, 'url', null) === _.get(child_page, 'url', null) })} > <Link to={withPrefix(_.get(child_page, 'url', null))}>{_.get(child_page, 'frontmatter.title', null)}</Link> </li> ))} </ul> ); } } Click to expand! Footer import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import ActionLink from './ActionLink'; export default class Footer extends React.Component { render() { return ( <footer id="colophon" className="site-footer outer"> <div className="inner"> <div className="site-footer-inside"> <p className="site-info"> {_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null) && ( <span className="copyright">{htmlToReact(_.get(this.props, 'pageContext.site.siteMetadata.footer.content', null))}</span> )} {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </p> {_.get(this.props, 'pageContext.site.siteMetadata.footer.has_social', null) && ( <div className="social-links"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.footer.social_links', null), (action, action_idx) => ( <ActionLink key={action_idx} {...this.props} action={action} /> ))} </div> )} </div> </div> </footer> ); } } Header import React from 'react'; import _ from 'lodash'; import { Link, withPrefix, classNames } from '../utils'; import ActionLink from './ActionLink'; import Submenu from './Submenu'; export default class Header extends React.Component { render() { return ( <header id="masthead" className="site-header outer"> <div className="inner"> <div className="site-header-inside"> <div className="site-branding"> {_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null) ? ( <p className="site-logo"> <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> <img src={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img', null))} alt={_.get(this.props, 'pageContext.site.siteMetadata.header.logo_img_alt', null)} /> </Link> </p> ) : ( <p className="site-title"> {' '} WebDevHub <Link to={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.header.url', null) || '/')}> {_.get(this.props, 'pageContext.site.siteMetadata.header.title', null)} </Link> </p> )} </div> <div id="search" className="inner"></div> {_.get(this.props, 'pageContext.site.siteMetadata.header.has_nav', null) && ( <React.Fragment> <nav id="main-navigation" className="site-navigation" aria-label="Main Navigation"> <div className="site-nav-inside"> <button id="menu-close" className="menu-toggle"> <span className="screen-reader-text">Open Menu</span> <span className="icon-close" aria-hidden="true" /> </button> <ul className="menu"> {_.map(_.get(this.props, 'pageContext.site.siteMetadata.header.nav_links', null), (action, action_idx) => { let page_url = _.trim(_.get(this.props, 'pageContext.url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { 'has-children': _.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null), current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> {_.get(action, 'has_subnav', null) && _.get(action, 'subnav_links', null) && ( <React.Fragment> <button className="submenu-toggle"> <span className="icon-angle-right" aria-hidden="true" /> <span className="screen-reader-text">Sub-menu</span> </button> <Submenu {...this.props} submenu={_.get(action, 'subnav_links', null)} menu_class={'submenu'} page={this.props.pageContext} /> </React.Fragment> )} </li> ); })} </ul> </div> </nav> <button id="menu-open" className="menu-toggle"> <span className="screen-reader-text">Close Menu</span> <span className="icon-menu" aria-hidden="true" /> </button> </React.Fragment> )} </div> </div> <div id="search" className="inner"></div> <div> <a className="github-corner" href="https://github.com/bgoonz/BGOONZ_BLOG_2.0" aria-label="View source on Github"> <svg aria-hidden="true" width={80} height={80} viewBox="0 0 250 250" style={{ zIndex: 100000, fill: '#194ccdaf', color: '#fff', position: 'fixed', top: '20px', border: 0, left: '20px', transform: 'scale(-1.5, 1.5)' }} > <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path> <path className="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style={{ transformOrigin: '130px 106px' }} ></path> <path className="octo-body" d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" ></path> </svg> </a> </div> </header> ); } } Click to expand! Icon import React from 'react'; import _ from 'lodash'; export default class Icon extends React.Component { render() { let icon = _.get(this.props, 'icon', null); return ( <svg className="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> {icon === 'dev' ? ( <path d="M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z" /> ) : icon === 'facebook' ? ( <path d="M23.998 12c0-6.628-5.372-12-11.999-12C5.372 0 0 5.372 0 12c0 5.988 4.388 10.952 10.124 11.852v-8.384H7.078v-3.469h3.046V9.356c0-3.008 1.792-4.669 4.532-4.669 1.313 0 2.686.234 2.686.234v2.953H15.83c-1.49 0-1.955.925-1.955 1.874V12h3.328l-.532 3.469h-2.796v8.384c5.736-.9 10.124-5.864 10.124-11.853z" /> ) : icon === 'github' ? ( <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" /> ) : icon === 'instagram' ? ( <path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913a5.885 5.885 0 001.384 2.126A5.868 5.868 0 004.14 23.37c.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558a5.898 5.898 0 002.126-1.384 5.86 5.86 0 001.384-2.126c.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913a5.89 5.89 0 00-1.384-2.126A5.847 5.847 0 0019.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.899 1.382 3.744 3.744 0 01-1.38.896c-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.38c-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 01-2.88 0 1.44 1.44 0 012.88 0z" /> ) : icon === 'linkedin' ? ( <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" /> ) : icon === 'pinterest' ? ( <path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z" /> ) : icon === 'reddit' ? ( <path d="M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z" /> ) : icon === 'twitter' ? ( <path d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z" /> ) : icon === 'youtube' ? ( <path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z" /> ) : ( icon === 'vimeo' && ( <path d="M23.977 6.416c-.105 2.338-1.739 5.543-4.894 9.609-3.268 4.247-6.026 6.37-8.29 6.37-1.409 0-2.578-1.294-3.553-3.881L5.322 11.4C4.603 8.816 3.834 7.522 3.01 7.522c-.179 0-.806.378-1.881 1.132L0 7.197a315.065 315.065 0 003.501-3.128C5.08 2.701 6.266 1.984 7.055 1.91c1.867-.18 3.016 1.1 3.447 3.838.465 2.953.789 4.789.971 5.507.539 2.45 1.131 3.674 1.776 3.674.502 0 1.256-.796 2.265-2.385 1.004-1.589 1.54-2.797 1.612-3.628.144-1.371-.395-2.061-1.614-2.061-.574 0-1.167.121-1.777.391 1.186-3.868 3.434-5.757 6.762-5.637 2.473.06 3.628 1.664 3.493 4.797l-.013.01z" /> ) )} </svg> ); } } Click to expand! Body import React from 'react'; import { Helmet } from 'react-helmet'; import _ from 'lodash'; import { withPrefix, attribute } from '../utils'; import '../sass/main.scss'; import Header from './Header'; import Footer from './Footer'; export default class Body extends React.Component { render() { return ( <React.Fragment> <Helmet> <title> {_.get(this.props, 'pageContext.frontmatter.seo.title', null) ? _.get(this.props, 'pageContext.frontmatter.seo.title', null) : _.get(this.props, 'pageContext.frontmatter.title', null) + ' | ' + _.get(this.props, 'pageContext.site.siteMetadata.title', null)} </title> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initialScale=1.0" /> <meta name="description" content={_.get(this.props, 'pageContext.frontmatter.seo.description', null) || ''} /> {_.get(this.props, 'pageContext.frontmatter.seo.robots', null) && ( <meta name="robots" content={_.join(_.get(this.props, 'pageContext.frontmatter.seo.robots', null), ',')} /> )} {_.map(_.get(this.props, 'pageContext.frontmatter.seo.extra', null), (meta, meta_idx) => { let key_name = _.get(meta, 'keyName', null) || 'name'; return _.get(meta, 'relativeUrl', null) ? ( _.get(this.props, 'pageContext.site.siteMetadata.domain', null) && (() => { let domain = _.trim(_.get(this.props, 'pageContext.site.siteMetadata.domain', null), '/'); let rel_url = withPrefix(_.get(meta, 'value', null)); let full_url = domain + rel_url; return <meta key={meta_idx} {...attribute(key_name, _.get(meta, 'name', null))} content={full_url} />; })() ) : ( <meta key={meta_idx + '.1'} {...attribute(key_name, _.get(meta, 'name', null))} content={_.get(meta, 'value', null)} /> ); })} <link rel="preconnect" href="https://fonts.gstatic.com" /> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> {_.get(this.props, 'pageContext.site.siteMetadata.favicon', null) && ( <link rel="icon" href={withPrefix(_.get(this.props, 'pageContext.site.siteMetadata.favicon', null))} /> )} <body className={'palette-' + _.get(this.props, 'pageContext.site.siteMetadata.palette', null)} /> </Helmet> <div id="page" className="site"> <Header {...this.props} /> <main id="content" className="site-content"> {this.props.children} </main> <Footer {...this.props} /> </div> </React.Fragment> ); } } Click to expand! SectionContent import React from 'react'; import _ from 'lodash'; import { classNames, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionContent extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-text outer"> <div className="outter"> <div className={classNames('inner', { 'grid-swap': _.get(section, 'image', null) && _.get(section, 'image_position', null) === 'right' })} > {_.get(section, 'image', null) && ( <div className="grid-item block-image"> <img src={withPrefix(_.get(section, 'image', null))} alt={_.get(section, 'image_alt', null)} /> </div> )} <div> {_.get(section, 'title', null) && ( <div className="block-header"> <h2 className="block-title">{_.get(section, 'title', null)}</h2> </div> )} {_.get(section, 'content', null) && <div className="outer">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionCta import React from 'react'; import _ from 'lodash'; import { htmlToReact } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionCta extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-cta outer"> <div className="inner"> <div className="has-gradient"> <div className="grid grid-middle grid-center"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="grid-item block-header"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'actions', null) && ( <div className="grid-item block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </div> </div> </section> ); } } Click to expand! SectionDocs import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, pathJoin, getPage, Link, withPrefix } from '../utils'; export default class SectionDocs extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(this.props, 'pageContext.site.data.doc_sections.sections', null), (doc_section, doc_section_idx) => { let doc_section_path = pathJoin(_.get(this.props, 'pageContext.site.data.doc_sections.root_docs_path', null), doc_section); let doc_section_page = getPage(this.props.pageContext.pages, doc_section_path); return ( <div key={doc_section_idx} className="grid-item"> <div className="grid-item-inside"> <h3 className="grid-item-title line-left"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}> {_.get(doc_section_page, 'frontmatter.title', null)} </Link> </h3> {_.get(doc_section_page, 'frontmatter.excerpt', null) && ( <div className="grid-item-content"> <p>{htmlToReact(_.get(doc_section_page, 'frontmatter.excerpt', null))}</p> </div> )} <div className="grid-item-buttons"> <Link to={withPrefix(_.get(doc_section_page, 'url', null))}>Learn More</Link> </div> </div> </div> ); })} </div> </div> </div> </section> ); } } Click to expand! SectionGrid import React from 'react'; import _ from 'lodash'; import { classNames, htmlToReact, withPrefix, Link, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionGrid extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className={classNames('block', 'block-grid', 'outer', { 'has-header': _.get(section, 'title', null) || _.get(section, 'subtitle', null) })} > <div className="inner"> {(_.get(section, 'title', null) || _.get(section, 'subtitle', null)) && ( <div className="block-header inner-sm"> {_.get(section, 'title', null) && <h2 className="block-title">{_.get(section, 'title', null)}</h2>} {_.get(section, 'subtitle', null) && <p className="block-subtitle">{htmlToReact(_.get(section, 'subtitle', null))}</p>} </div> )} {_.get(section, 'grid_items', null) && ( <div className="block-content"> <div className={classNames('grid', { 'grid-col-2': _.get(section, 'col_number', null) === 'two', 'grid-col-3': _.get(section, 'col_number', null) === 'three' })} > {_.map(_.get(section, 'grid_items', null), (item, item_idx) => ( <div key={item_idx} className="grid-item"> <div className="grid-item-inside"> {_.get(item, 'image', null) && ( <div className="grid-item-image"> <img src={withPrefix(_.get(item, 'image', null))} alt={_.get(item, 'image_alt', null)} /> </div> )} {_.get(item, 'title', null) && ( <h3 className="grid-item-title line-left"> {_.get(item, 'title_url', null) ? ( <Link to={withPrefix(_.get(item, 'title_url', null))}>{_.get(item, 'title', null)}</Link> ) : ( _.get(item, 'title', null) )} </h3> )} {_.get(item, 'content', null) && ( <div className="grid-item-content">{markdownify(_.get(item, 'content', null))}</div> )} {_.get(item, 'actions', null) && ( <div className="grid-item-buttons"> <CtaButtons {...this.props} actions={_.get(item, 'actions', null)} /> </div> )} </div> </div> ))} </div> </div> )} </div> </section> ); } } Click to expand! SectionHero import React from 'react'; import _ from 'lodash'; import { toStyleObj, withPrefix, markdownify } from '../utils'; import CtaButtons from './CtaButtons'; export default class SectionHero extends React.Component { render() { let section = _.get(this.props, 'section', null); return ( <section id={_.get(section, 'section_id', null)} className="block block-hero has-gradient outer"> {_.get(section, 'image', null) && ( <div className="bg-img" style={toStyleObj("background-image: url('" + withPrefix(_.get(section, 'image', null)) + "')")} /> )} <div className="inner-sm"> {_.get(section, 'title', null) && ( <div className="block-header"> <h1 className="block-title">{_.get(section, 'title', null)}</h1> </div> )} {_.get(section, 'content', null) && <div className="block-content">{markdownify(_.get(section, 'content', null))}</div>} {_.get(section, 'actions', null) && ( <div className="block-buttons"> <CtaButtons {...this.props} actions={_.get(section, 'actions', null)} /> </div> )} </div> </section> ); } } Click to expand! Submenu import React from 'react'; import _ from 'lodash'; import { classNames } from '../utils'; import ActionLink from './ActionLink'; export default class Submenu extends React.Component { render() { let page = _.get(this.props, 'page', null); return ( <ul className={_.get(this.props, 'menu_class', null)}> {_.map(_.get(this.props, 'submenu', null), (action, action_idx) => { let page_url = _.trim(_.get(page, 'url', null), '/'); let action_url = _.trim(_.get(action, 'url', null), '/'); return ( <li key={action_idx} className={classNames('menu-item', { current: page_url === action_url, 'menu-button': _.get(action, 'style', null) !== 'link' })} > <ActionLink {...this.props} action={action} /> </li> ); })} </ul> ); } } Click to expand! Index.js import ActionLink from './ActionLink'; import CtaButtons from './CtaButtons'; import DocsMenu from './DocsMenu'; import DocsSubmenu from './DocsSubmenu'; import Footer from './Footer'; import Header from './Header'; import Icon from './Icon'; import SectionContent from './SectionContent'; import SectionCta from './SectionCta'; import SectionDocs from './SectionDocs'; import SectionGrid from './SectionGrid'; import SectionHero from './SectionHero'; import Submenu from './Submenu'; import Layout from './Layout'; export { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; export default { ActionLink, CtaButtons, DocsMenu, DocsSubmenu, Footer, Header, Icon, SectionContent, SectionCta, SectionDocs, SectionGrid, SectionHero, Submenu, Layout }; Static Javascript: Static Javascript:! main.js window.onGatsbyInitialClientRender = function () { /** * Main JS file for theme behaviours */ // Responsive video embeds let videoEmbeds = ['iframe[src*="youtube.com"]', 'iframe[src*="vimeo.com"]']; reframe(videoEmbeds.join(',')); // Handle main navigation menu toggling on small screens function menuToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('menu--opened'); } // Handle docs navigation menu toggling on small screens function docsNavToggleHandler(e) { e.preventDefault(); document.body.classList.toggle('docs-menu--opened'); } // Handle submenu toggling function submenuToggleHandler(e) { e.preventDefault(); this.parentNode.classList.toggle('active'); } window.addMainNavigationHandlers = function () { const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].addEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeMainNavigationHandlers = function () { // Remove nav related classes on page load document.body.classList.remove('menu--opened'); const menuToggle = document.querySelectorAll('.menu-toggle'); if (menuToggle) { for (let i = 0; i < menuToggle.length; i++) { menuToggle[i].removeEventListener('click', menuToggleHandler, false); } } const submenuToggle = document.querySelectorAll('.submenu-toggle'); if (submenuToggle) { for (let i = 0; i < submenuToggle.length; i++) { submenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addDocsNavigationHandlers = function () { const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.addEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].addEventListener('click', submenuToggleHandler, false); } } }; window.removeDocsNavigationHandlers = function () { // Remove docs nav related classes on page load document.body.classList.remove('docs-menu--opened'); const docsNavToggle = document.getElementById('docs-nav-toggle'); if (docsNavToggle) { docsNavToggle.removeEventListener('click', docsNavToggleHandler, false); } const docsSubmenuToggle = document.querySelectorAll('.docs-submenu-toggle'); if (docsSubmenuToggle) { for (let i = 0; i < docsSubmenuToggle.length; i++) { docsSubmenuToggle[i].removeEventListener('click', submenuToggleHandler, false); } } }; window.addPageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { const pageContent = document.querySelector('.type-docs .post-content'); // Create in-page navigation const headerLinks = getHeaderLinks({ root: pageContent }); if (headerLinks.length > 0) { pageToc.classList.add('has-links'); renderHeaderLinks(pageTocContainer, headerLinks); } // Scroll to anchors let scroll = new SmoothScroll('[data-scroll]'); let hash = window.decodeURI(location.hash.replace('#', '')); if (hash !== '') { window.setTimeout(function () { let anchor = document.getElementById(hash); if (anchor) { scroll.animateScroll(anchor); } }, 0); } // Highlight current anchor let pageTocLinks = pageTocContainer.getElementsByTagName('a'); if (pageTocLinks.length > 0) { let spy = new Gumshoe('#page-nav-inside a', { nested: true, nestedClass: 'active-parent' }); } // Add link to page content headings let pageHeadings = getElementsByTagNames(pageContent, ['h2', 'h3']); for (let i = 0; i < pageHeadings.length; i++) { let heading = pageHeadings[i]; if (typeof heading.id !== 'undefined' && heading.id !== '') { heading.insertBefore(anchorForId(heading.id), heading.firstChild); } } // Copy link url let clipboard = new ClipboardJS('.hash-link', { text: function (trigger) { return window.location.href.replace(window.location.hash, '') + trigger.getAttribute('href'); } }); } }; window.removePageNavLinks = function () { const pageToc = document.getElementById('page-nav-inside'); const pageTocContainer = document.getElementById('page-nav-link-container'); if (pageToc && pageTocContainer) { pageToc.classList.remove('has-links'); while (pageTocContainer.firstChild) { pageTocContainer.removeChild(pageTocContainer.firstChild); } } }; function getElementsByTagNames(root, tagNames) { let elements = []; for (let i = 0; i < root.children.length; i++) { let element = root.children[i]; let tagName = element.nodeName.toLowerCase(); if (tagNames.includes(tagName)) { elements.push(element); } elements = elements.concat(getElementsByTagNames(element, tagNames)); } return elements; } function createLinksForHeaderElements(elements) { let result = []; let stack = [ { level: 0, children: result } ]; let re = /^h(\d)$/; for (let i = 0; i < elements.length; i++) { let element = elements[i]; let tagName = element.nodeName.toLowerCase(); let match = re.exec(tagName); if (!match) { console.warn('can not create links to non header element'); continue; } let headerLevel = parseInt(match[1], 10); if (!element.id) { if (!element.textContent) { console.warn('can not create link to element without id and without text content'); continue; } element.id = element.textContent .toLowerCase() .replace(/[^\w]+/g, '_') .replace(/^_/, '') .replace(/_$/, ''); } let link = document.createElement('a'); link.href = '#' + element.id; link.setAttribute('data-scroll', ''); link.appendChild(document.createTextNode(element.textContent)); let obj = { id: element.id, level: headerLevel, textContent: element.textContent, element: element, link: link, children: [] }; if (headerLevel > stack[stack.length - 1].level) { stack[stack.length - 1].children.push(obj); stack.push(obj); } else { while (headerLevel <= stack[stack.length - 1].level && stack.length > 1) { stack.pop(); } stack[stack.length - 1].children.push(obj); stack.push(obj); } } return result; } function getHeaderLinks(options = {}) { let tagNames = options.tagNames || ['h2', 'h3']; let root = options.root || document.body; let headerElements = getElementsByTagNames(root, tagNames); return createLinksForHeaderElements(headerElements); } function renderHeaderLinks(element, links) { if (links.length === 0) { return; } let ulElm = document.createElement('ul'); for (let i = 0; i < links.length; i++) { let liElm = document.createElement('li'); liElm.append(links[i].link); if (links[i].children.length > 0) { renderHeaderLinks(liElm, links[i].children); } ulElm.appendChild(liElm); } element.appendChild(ulElm); } function anchorForId(id) { let anchor = document.createElement('a'); anchor.setAttribute('class', 'hash-link'); anchor.setAttribute('data-scroll', ''); anchor.href = '#' + id; anchor.innerHTML = '<span class="screen-reader-text">Copy</span>'; return anchor; } // Syntax Highlighter // Prism.highlightAll(); }; //----------------------------------------------------------------------- //----------------------------------------------------------------------- //--------------------------------New---------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- Page Load JS window.onGatsbyRouteUpdate = function () { window.addMainNavigationHandlers(); window.addDocsNavigationHandlers(); window.addPageNavLinks(); }; PageUnload.js window.onGatsbyPreRouteUpdate = function () { window.removeMainNavigationHandlers(); window.removeDocsNavigationHandlers(); window.removePageNavLinks(); }; Plugins.js!(function (e, t) { 'object' == typeof exports && 'undefined' != typeof module ? (module.exports = t()) : 'function' == typeof define && define.amd ? define(t) : ((e = 'undefined' != typeof globalThis ? globalThis : e || self).reframe = t()); })(this, function () { 'use strict'; function t() { for (var e = 0, t = 0, n = arguments.length; t < n; t++) e += arguments[t].length; for (var i = Array(e), o = 0, t = 0; t < n; t++) for (var r = arguments[t], f = 0, d = r.length; f < d; f++, o++) i[o] = r[f]; return i; } return function (e, s) { return ( void 0 === s && (s = 'js-reframe'), ('string' == typeof e ? t(document.querySelectorAll(e)) : 'length' in e ? t(e) : [e]).forEach(function (e) { var t, n, i, o, r, f, d, l; -1 !== e.className.split(' ').indexOf(s) || -1 < e.style.width.indexOf('%') || ((i = e.getAttribute('height') || e.offsetHeight), (o = e.getAttribute('width') || e.offsetWidth), (r = (('string' == typeof i ? parseInt(i) : i) / ('string' == typeof o ? parseInt(o) : o)) * 100), ((f = document.createElement('div')).className = s), ((d = f.style).position = 'relative'), (d.width = '100%'), (d.paddingTop = r + '%'), ((l = e.style).position = 'absolute'), (l.width = '100%'), (l.height = '100%'), (l.left = '0'), (l.top = '0'), null !== (t = e.parentNode) && void 0 !== t && t.insertBefore(f, e), null !== (n = e.parentNode) && void 0 !== n && n.removeChild(e), f.appendChild(e)); }) ); }; }); /*! smooth-scroll v16.1.0 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/smooth-scroll */ window.Element && !Element.prototype.closest && (Element.prototype.closest = function (e) { var t, n = (this.document || this.ownerDocument).querySelectorAll(e), o = this; do { for (t = n.length; 0 <= --t && n.item(t) !== o; ); } while (t < 0 && (o = o.parentElement)); return o; }), (function () { if ('function' == typeof window.CustomEvent) return; function e(e, t) { t = t || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(e, t.bubbles, t.cancelable, t.detail), n; } (e.prototype = window.Event.prototype), (window.CustomEvent = e); })(), (function () { for (var r = 0, e = ['ms', 'moz', 'webkit', 'o'], t = 0; t < e.length && !window.requestAnimationFrame; ++t) (window.requestAnimationFrame = window[e[t] + 'RequestAnimationFrame']), (window.cancelAnimationFrame = window[e[t] + 'CancelAnimationFrame'] || window[e[t] + 'CancelRequestAnimationFrame']); window.requestAnimationFrame || (window.requestAnimationFrame = function (e, t) { var n = new Date().getTime(), o = Math.max(0, 16 - (n - r)), a = window.setTimeout(function () { e(n + o); }, o); return (r = n + o), a; }), window.cancelAnimationFrame || (window.cancelAnimationFrame = function (e) { clearTimeout(e); }); })(), (function (e, t) { 'function' == typeof define && define.amd ? define([], function () { return t(e); }) : 'object' == typeof exports ? (module.exports = t(e)) : (e.SmoothScroll = t(e)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (q) { 'use strict'; var I = { ignore: '[data-scroll-ignore]', header: null, topOnEmptyHash: !0, speed: 500, speedAsDuration: !1, durationMax: null, durationMin: null, clip: !0, offset: 0, easing: 'easeInOutCubic', customEasing: null, updateURL: !0, popstate: !0, emitEvents: !0 }, F = function () { var n = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var t in e) { if (!e.hasOwnProperty(t)) return; n[t] = e[t]; } }), n ); }, r = function (e) { '#' === e.charAt(0) && (e = e.substr(1)); for (var t, n = String(e), o = n.length, a = -1, r = '', i = n.charCodeAt(0); ++a < o; ) { if (0 === (t = n.charCodeAt(a))) throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); (1 <= t && t <= 31) || 127 == t || (0 === a && 48 <= t && t <= 57) || (1 === a && 48 <= t && t <= 57 && 45 === i) ? (r += '\\' + t.toString(16) + ' ') : (r += 128 <= t || 45 === t || 95 === t || (48 <= t && t <= 57) || (65 <= t && t <= 90) || (97 <= t && t <= 122) ? n.charAt(a) : '\\' + n.charAt(a)); } return '#' + r; }, L = function () { return Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ); }, x = function (e) { return e ? ((t = e), parseInt(q.getComputedStyle(t).height, 10) + e.offsetTop) : 0; var t; }, H = function (e, t, n, o) { if (t.emitEvents && 'function' == typeof q.CustomEvent) { var a = new CustomEvent(e, { bubbles: !0, detail: { anchor: n, toggle: o } }); document.dispatchEvent(a); } }; return function (o, e) { var A, a, O, C, M = {}; (M.cancelScroll = function (e) { cancelAnimationFrame(C), (C = null), e || H('scrollCancel', A); }), (M.animateScroll = function (i, c, e) { M.cancelScroll(); var s = F(A || I, e || {}), u = '[object Number]' === Object.prototype.toString.call(i), t = u || !i.tagName ? null : i; if (u || t) { var l = q.pageYOffset; s.header && !O && (O = document.querySelector(s.header)); var n, o, a, m, r, d, f, h, p = x(O), g = u ? i : (function (e, t, n, o) { var a = 0; if (e.offsetParent) for (; (a += e.offsetTop), (e = e.offsetParent); ); return (a = Math.max(a - t - n, 0)), o && (a = Math.min(a, L() - q.innerHeight)), a; })(t, p, parseInt('function' == typeof s.offset ? s.offset(i, c) : s.offset, 10), s.clip), y = g - l, v = L(), w = 0, S = ((n = y), (a = (o = s).speedAsDuration ? o.speed : Math.abs((n / 1e3) * o.speed)), o.durationMax && a > o.durationMax ? o.durationMax : o.durationMin && a < o.durationMin ? o.durationMin : parseInt(a, 10)), E = function (e, t) { var n, o, a, r = q.pageYOffset; if (e == t || r == t || (l < t && q.innerHeight + r) >= v) return ( M.cancelScroll(!0), (o = t), (a = u), 0 === (n = i) && document.body.focus(), a || (n.focus(), document.activeElement !== n && (n.setAttribute('tabindex', '-1'), n.focus(), (n.style.outline = 'none')), q.scrollTo(0, o)), H('scrollStop', s, i, c), !(C = m = null) ); }, b = function (e) { var t, n, o; m || (m = e), (w += e - m), (d = l + y * ((n = r = 1 < (r = 0 === S ? 0 : w / S) ? 1 : r), 'easeInQuad' === (t = s).easing && (o = n * n), 'easeOutQuad' === t.easing && (o = n * (2 - n)), 'easeInOutQuad' === t.easing && (o = n < 0.5 ? 2 * n * n : (4 - 2 * n) * n - 1), 'easeInCubic' === t.easing && (o = n * n * n), 'easeOutCubic' === t.easing && (o = --n * n * n + 1), 'easeInOutCubic' === t.easing && (o = n < 0.5 ? 4 * n * n * n : (n - 1) * (2 * n - 2) * (2 * n - 2) + 1), 'easeInQuart' === t.easing && (o = n * n * n * n), 'easeOutQuart' === t.easing && (o = 1 - --n * n * n * n), 'easeInOutQuart' === t.easing && (o = n < 0.5 ? 8 * n * n * n * n : 1 - 8 * --n * n * n * n), 'easeInQuint' === t.easing && (o = n * n * n * n * n), 'easeOutQuint' === t.easing && (o = 1 + --n * n * n * n * n), 'easeInOutQuint' === t.easing && (o = n < 0.5 ? 16 * n * n * n * n * n : 1 + 16 * --n * n * n * n * n), t.customEasing && (o = t.customEasing(n)), o || n)), q.scrollTo(0, Math.floor(d)), E(d, g) || ((C = q.requestAnimationFrame(b)), (m = e)); }; 0 === q.pageYOffset && q.scrollTo(0, 0), (f = i), (h = s), u || (history.pushState && h.updateURL && history.pushState( { smoothScroll: JSON.stringify(h), anchor: f.id }, document.title, f === document.documentElement ? '#top' : '#' + f.id )), 'matchMedia' in q && q.matchMedia('(prefers-reduced-motion)').matches ? q.scrollTo(0, Math.floor(g)) : (H('scrollStart', s, i, c), M.cancelScroll(!0), q.requestAnimationFrame(b)); } }); var t = function (e) { if ( !e.defaultPrevented && !(0 !== e.button || e.metaKey || e.ctrlKey || e.shiftKey) && 'closest' in e.target && (a = e.target.closest(o)) && 'a' === a.tagName.toLowerCase() && !e.target.closest(A.ignore) && a.hostname === q.location.hostname && a.pathname === q.location.pathname && /#/.test(a.href) ) { var t, n = r(a.hash); if ('#' === n) { if (!A.topOnEmptyHash) return; t = document.documentElement; } else t = document.querySelector(n); (t = t || '#top' !== n ? t : document.documentElement) && (e.preventDefault(), (function (e) { if (history.replaceState && e.updateURL && !history.state) { var t = q.location.hash; (t = t || ''), history.replaceState( { smoothScroll: JSON.stringify(e), anchor: t || q.pageYOffset }, document.title, t || q.location.href ); } })(A), M.animateScroll(t, a)); } }, n = function (e) { if (null !== history.state && history.state.smoothScroll && history.state.smoothScroll === JSON.stringify(A)) { var t = history.state.anchor; ('string' == typeof t && t && !(t = document.querySelector(r(history.state.anchor)))) || M.animateScroll(t, null, { updateURL: !1 }); } }; M.destroy = function () { A && (document.removeEventListener('click', t, !1), q.removeEventListener('popstate', n, !1), M.cancelScroll(), (C = O = a = A = null)); }; return ( (function () { if (!('querySelector' in document && 'addEventListener' in q && 'requestAnimationFrame' in q && 'closest' in q.Element.prototype)) throw 'Smooth Scroll: This browser does not support the required JavaScript methods and browser APIs.'; M.destroy(), (A = F(I, e || {})), (O = A.header ? document.querySelector(A.header) : null), document.addEventListener('click', t, !1), A.updateURL && A.popstate && q.addEventListener('popstate', n, !1); })(), M ); }; }); /*! gumshoejs v5.1.1 | (c) 2019 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/gumshoe */ Element.prototype.closest || (Element.prototype.matches || (Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector), (Element.prototype.closest = function (t) { var e = this; if (!document.documentElement.contains(this)) return null; do { if (e.matches(t)) return e; e = e.parentElement; } while (null !== e); return null; })), (function () { if ('function' == typeof window.CustomEvent) return !1; function t(t, e) { e = e || { bubbles: !1, cancelable: !1, detail: void 0 }; var n = document.createEvent('CustomEvent'); return n.initCustomEvent(t, e.bubbles, e.cancelable, e.detail), n; } (t.prototype = window.Event.prototype), (window.CustomEvent = t); })(), (function (t, e) { 'function' == typeof define && define.amd ? define([], function () { return e(t); }) : 'object' == typeof exports ? (module.exports = e(t)) : (t.Gumshoe = e(t)); })('undefined' != typeof global ? global : 'undefined' != typeof window ? window : this, function (t) { 'use strict'; var e = { navClass: 'active', contentClass: 'active', nested: !1, nestedClass: 'active', offset: 0, reflow: !1, events: !0 }, n = function (t, e, n) { if (n.settings.events) { var o = new CustomEvent(t, { bubbles: !0, cancelable: !0, detail: n }); e.dispatchEvent(o); } }, o = function (t) { var e = 0; if (t.offsetParent) for (; t; ) (e += t.offsetTop), (t = t.offsetParent); return e >= 0 ? e : 0; }, s = function (t) { t && t.sort(function (t, e) { return o(t.content) < o(e.content) ? -1 : 1; }); }, c = function (e, n, o) { var s = e.getBoundingClientRect(), c = (function (t) { return 'function' == typeof t.offset ? parseFloat(t.offset()) : parseFloat(t.offset); })(n); return o ? parseInt(s.bottom, 10) < (t.innerHeight || document.documentElement.clientHeight) : parseInt(s.top, 10) <= c; }, r = function () { return ( t.innerHeight + t.pageYOffset >= Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) ); }, i = function (t, e) { var n = t[t.length - 1]; if ( (function (t, e) { return !(!r() || !c(t.content, e, !0)); })(n, e) ) return n; for (var o = t.length - 1; o >= 0; o--) if (c(t[o].content, e)) return t[o]; }, l = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.remove(e.nestedClass), l(n, e)); } }, a = function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.remove(e.navClass), t.content.classList.remove(e.contentClass), l(o, e), n('gumshoeDeactivate', o, { link: t.nav, content: t.content, settings: e })); } }, u = function (t, e) { if (e.nested) { var n = t.parentNode.closest('li'); n && (n.classList.add(e.nestedClass), u(n, e)); } }; return function (o, c) { var r, l, f, d, m, v = {}; (v.setup = function () { (r = document.querySelectorAll(o)), (l = []), Array.prototype.forEach.call(r, function (t) { var e = document.getElementById(decodeURIComponent(t.hash.substr(1))); e && l.push({ nav: t, content: e }); }), s(l); }), (v.detect = function () { var t = i(l, m); t ? (f && t.content === f.content) || (a(f, m), (function (t, e) { if (t) { var o = t.nav.closest('li'); o && (o.classList.add(e.navClass), t.content.classList.add(e.contentClass), u(o, e), n('gumshoeActivate', o, { link: t.nav, content: t.content, settings: e })); } })(t, m), (f = t)) : f && (a(f, m), (f = null)); }); var p = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(v.detect)); }, h = function (e) { d && t.cancelAnimationFrame(d), (d = t.requestAnimationFrame(function () { s(l), v.detect(); })); }; v.destroy = function () { f && a(f, m), t.removeEventListener('scroll', p, !1), m.reflow && t.removeEventListener('resize', h, !1), (l = null), (r = null), (f = null), (d = null), (m = null); }; return ( (m = (function () { var t = {}; return ( Array.prototype.forEach.call(arguments, function (e) { for (var n in e) { if (!e.hasOwnProperty(n)) return; t[n] = e[n]; } }), t ); })(e, c || {})), v.setup(), v.detect(), t.addEventListener('scroll', p, !1), m.reflow && t.addEventListener('resize', h, !1), v ); }; }); /*! * clipboard.js v2.0.4 * https://zenorocha.github.io/clipboard.js * * Licensed MIT © Zeno Rocha */ !(function (t, e) { 'object' == typeof exports && 'object' == typeof module ? (module.exports = e()) : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? (exports.ClipboardJS = e()) : (t.ClipboardJS = e()); })(this, function () { return (function (n) { var o = {}; function r(t) { if (o[t]) return o[t].exports; var e = (o[t] = { i: t, l: !1, exports: {} }); return n[t].call(e.exports, e, e.exports, r), (e.l = !0), e.exports; } return ( (r.m = n), (r.c = o), (r.d = function (t, e, n) { r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: n }); }), (r.r = function (t) { 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), Object.defineProperty(t, '__esModule', { value: !0 }); }), (r.t = function (e, t) { if ((1 & t && (e = r(e)), 8 & t)) return e; if (4 & t && 'object' == typeof e && e && e.__esModule) return e; var n = Object.create(null); if ( (r.r(n), Object.defineProperty(n, 'default', { enumerable: !0, value: e }), 2 & t && 'string' != typeof e) ) for (var o in e) r.d( n, o, function (t) { return e[t]; }.bind(null, o) ); return n; }), (r.n = function (t) { var e = t && t.__esModule ? function () { return t.default; } : function () { return t; }; return r.d(e, 'a', e), e; }), (r.o = function (t, e) { return Object.prototype.hasOwnProperty.call(t, e); }), (r.p = ''), r((r.s = 0)) ); })([ function (t, e, n) { 'use strict'; var r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = o(n(1)), c = o(n(3)), u = o(n(4)); function o(t) { return t && t.__esModule ? t : { default: t }; } var l = (function (t) { function o(t, e) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, o); var n = (function (t, e) { if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return !e || ('object' != typeof e && 'function' != typeof e) ? t : e; })(this, (o.__proto__ || Object.getPrototypeOf(o)).call(this)); return n.resolveOptions(e), n.listenClick(t), n; } return ( (function (t, e) { if ('function' != typeof e && null !== e) throw new TypeError('Super expression must either be null or a function, not ' + typeof e); (t.prototype = Object.create(e && e.prototype, { constructor: { value: t, enumerable: !1, writable: !0, configurable: !0 } })), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : (t.__proto__ = e)); })(o, c.default), i( o, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = 'function' == typeof t.action ? t.action : this.defaultAction), (this.target = 'function' == typeof t.target ? t.target : this.defaultTarget), (this.text = 'function' == typeof t.text ? t.text : this.defaultText), (this.container = 'object' === r(t.container) ? t.container : document.body); } }, { key: 'listenClick', value: function (t) { var e = this; this.listener = (0, u.default)(t, 'click', function (t) { return e.onClick(t); }); } }, { key: 'onClick', value: function (t) { var e = t.delegateTarget || t.currentTarget; this.clipboardAction && (this.clipboardAction = null), (this.clipboardAction = new a.default({ action: this.action(e), target: this.target(e), text: this.text(e), container: this.container, trigger: e, emitter: this })); } }, { key: 'defaultAction', value: function (t) { return s('action', t); } }, { key: 'defaultTarget', value: function (t) { var e = s('target', t); if (e) return document.querySelector(e); } }, { key: 'defaultText', value: function (t) { return s('text', t); } }, { key: 'destroy', value: function () { this.listener.destroy(), this.clipboardAction && (this.clipboardAction.destroy(), (this.clipboardAction = null)); } } ], [ { key: 'isSupported', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : ['copy', 'cut'], e = 'string' == typeof t ? [t] : t, n = !!document.queryCommandSupported; return ( e.forEach(function (t) { n = n && !!document.queryCommandSupported(t); }), n ); } } ] ), o ); })(); function s(t, e) { var n = 'data-clipboard-' + t; if (e.hasAttribute(n)) return e.getAttribute(n); } t.exports = l; }, function (t, e, n) { 'use strict'; var o, r = 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator ? function (t) { return typeof t; } : function (t) { return t && 'function' == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? 'symbol' : typeof t; }, i = (function () { function o(t, e) { for (var n = 0; n < e.length; n++) { var o = e[n]; (o.enumerable = o.enumerable || !1), (o.configurable = !0), 'value' in o && (o.writable = !0), Object.defineProperty(t, o.key, o); } } return function (t, e, n) { return e && o(t.prototype, e), n && o(t, n), t; }; })(), a = n(2), c = (o = a) && o.__esModule ? o : { default: o }; var u = (function () { function e(t) { !(function (t, e) { if (!(t instanceof e)) throw new TypeError('Cannot call a class as a function'); })(this, e), this.resolveOptions(t), this.initSelection(); } return ( i(e, [ { key: 'resolveOptions', value: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; (this.action = t.action), (this.container = t.container), (this.emitter = t.emitter), (this.target = t.target), (this.text = t.text), (this.trigger = t.trigger), (this.selectedText = ''); } }, { key: 'initSelection', value: function () { this.text ? this.selectFake() : this.target && this.selectTarget(); } }, { key: 'selectFake', value: function () { var t = this, e = 'rtl' == document.documentElement.getAttribute('dir'); this.removeFake(), (this.fakeHandlerCallback = function () { return t.removeFake(); }), (this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || !0), (this.fakeElem = document.createElement('textarea')), (this.fakeElem.style.fontSize = '12pt'), (this.fakeElem.style.border = '0'), (this.fakeElem.style.padding = '0'), (this.fakeElem.style.margin = '0'), (this.fakeElem.style.position = 'absolute'), (this.fakeElem.style[e ? 'right' : 'left'] = '-9999px'); var n = window.pageYOffset || document.documentElement.scrollTop; (this.fakeElem.style.top = n + 'px'), this.fakeElem.setAttribute('readonly', ''), (this.fakeElem.value = this.text), this.container.appendChild(this.fakeElem), (this.selectedText = (0, c.default)(this.fakeElem)), this.copyText(); } }, { key: 'removeFake', value: function () { this.fakeHandler && (this.container.removeEventListener('click', this.fakeHandlerCallback), (this.fakeHandler = null), (this.fakeHandlerCallback = null)), this.fakeElem && (this.container.removeChild(this.fakeElem), (this.fakeElem = null)); } }, { key: 'selectTarget', value: function () { (this.selectedText = (0, c.default)(this.target)), this.copyText(); } }, { key: 'copyText', value: function () { var e = void 0; try { e = document.execCommand(this.action); } catch (t) { e = !1; } this.handleResult(e); } }, { key: 'handleResult', value: function (t) { this.emitter.emit(t ? 'success' : 'error', { action: this.action, text: this.selectedText, trigger: this.trigger, clearSelection: this.clearSelection.bind(this) }); } }, { key: 'clearSelection', value: function () { this.trigger && this.trigger.focus(), window.getSelection().removeAllRanges(); } }, { key: 'destroy', value: function () { this.removeFake(); } }, { key: 'action', set: function () { var t = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'copy'; if (((this._action = t), 'copy' !== this._action && 'cut' !== this._action)) throw new Error('Invalid "action" value, use either "copy" or "cut"'); }, get: function () { return this._action; } }, { key: 'target', set: function (t) { if (void 0 !== t) { if (!t || 'object' !== (void 0 === t ? 'undefined' : r(t)) || 1 !== t.nodeType) throw new Error('Invalid "target" value, use a valid Element'); if ('copy' === this.action && t.hasAttribute('disabled')) throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); if ('cut' === this.action && (t.hasAttribute('readonly') || t.hasAttribute('disabled'))) throw new Error( 'Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes' ); this._target = t; } }, get: function () { return this._target; } } ]), e ); })(); t.exports = u; }, function (t, e) { t.exports = function (t) { var e; if ('SELECT' === t.nodeName) t.focus(), (e = t.value); else if ('INPUT' === t.nodeName || 'TEXTAREA' === t.nodeName) { var n = t.hasAttribute('readonly'); n || t.setAttribute('readonly', ''), t.select(), t.setSelectionRange(0, t.value.length), n || t.removeAttribute('readonly'), (e = t.value); } else { t.hasAttribute('contenteditable') && t.focus(); var o = window.getSelection(), r = document.createRange(); r.selectNodeContents(t), o.removeAllRanges(), o.addRange(r), (e = o.toString()); } return e; }; }, function (t, e) { function n() {} (n.prototype = { on: function (t, e, n) { var o = this.e || (this.e = {}); return (o[t] || (o[t] = [])).push({ fn: e, ctx: n }), this; }, once: function (t, e, n) { var o = this; function r() { o.off(t, r), e.apply(n, arguments); } return (r._ = e), this.on(t, r, n); }, emit: function (t) { for (var e = [].slice.call(arguments, 1), n = ((this.e || (this.e = {}))[t] || []).slice(), o = 0, r = n.length; o < r; o++) n[o].fn.apply(n[o].ctx, e); return this; }, off: function (t, e) { var n = this.e || (this.e = {}), o = n[t], r = []; if (o && e) for (var i = 0, a = o.length; i < a; i++) o[i].fn !== e && o[i].fn._ !== e && r.push(o[i]); return r.length ? (n[t] = r) : delete n[t], this; } }), (t.exports = n); }, function (t, e, n) { var d = n(5), h = n(6); t.exports = function (t, e, n) { if (!t && !e && !n) throw new Error('Missing required arguments'); if (!d.string(e)) throw new TypeError('Second argument must be a String'); if (!d.fn(n)) throw new TypeError('Third argument must be a Function'); if (d.node(t)) return ( (s = e), (f = n), (l = t).addEventListener(s, f), { destroy: function () { l.removeEventListener(s, f); } } ); if (d.nodeList(t)) return ( (a = t), (c = e), (u = n), Array.prototype.forEach.call(a, function (t) { t.addEventListener(c, u); }), { destroy: function () { Array.prototype.forEach.call(a, function (t) { t.removeEventListener(c, u); }); } } ); if (d.string(t)) return (o = t), (r = e), (i = n), h(document.body, o, r, i); throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); var o, r, i, a, c, u, l, s, f; }; }, function (t, n) { (n.node = function (t) { return void 0 !== t && t instanceof HTMLElement && 1 === t.nodeType; }), (n.nodeList = function (t) { var e = Object.prototype.toString.call(t); return void 0 !== t && ('[object NodeList]' === e || '[object HTMLCollection]' === e) && 'length' in t && (0 === t.length || n.node(t[0])); }), (n.string = function (t) { return 'string' == typeof t || t instanceof String; }), (n.fn = function (t) { return '[object Function]' === Object.prototype.toString.call(t); }); }, function (t, e, n) { var a = n(7); function i(t, e, n, o, r) { var i = function (e, n, t, o) { return function (t) { (t.delegateTarget = a(t.target, n)), t.delegateTarget && o.call(e, t); }; }.apply(this, arguments); return ( t.addEventListener(n, i, r), { destroy: function () { t.removeEventListener(n, i, r); } } ); } t.exports = function (t, e, n, o, r) { return 'function' == typeof t.addEventListener ? i.apply(null, arguments) : 'function' == typeof n ? i.bind(null, document).apply(null, arguments) : ('string' == typeof t && (t = document.querySelectorAll(t)), Array.prototype.map.call(t, function (t) { return i(t, e, n, o, r); })); }; }, function (t, e) { if ('undefined' != typeof Element && !Element.prototype.matches) { var n = Element.prototype; n.matches = n.matchesSelector || n.mozMatchesSelector || n.msMatchesSelector || n.oMatchesSelector || n.webkitMatchesSelector; } t.exports = function (t, e) { for (; t && 9 !== t.nodeType; ) { if ('function' == typeof t.matches && t.matches(e)) return t; t = t.parentNode; } }; } ]); }); Prism.js ```js /* PrismJS 1.16.0 https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript&plugins=toolbar+copy-to-clipboard _/ var _self = 'undefined' != typeof window ? window : 'undefined' != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? self : {}, Prism = (function (g) { var c = /\blang(?:uage)?-([\w-]+)\b/i, a = 0, C = { manual: g.Prism && g.Prism.manual, disableWorkerMessageHandler: g.Prism && g.Prism.disableWorkerMessageHandler, util: { encode: function (e) { return e instanceof M? new M(e.type, C.util.encode(e.content), e.alias): Array.isArray(e)? e.map(C.util.encode): e.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' ');}, type: function (e) { return Object.prototype.toString.call(e).slice(8, -1);}, objId: function (e) { return e. id || Object.defineProperty(e, ' id', { value: ++a }), e.__id;}, clone: function n(e, t) { var r, a, i = C.util.type(e); switch (((t = t || {}), i)) { case 'Object': if (((a = C.util.objId(e)), t[a])) return t[a]; for (var l in ((r = {}), (t[a] = r), e)) e.hasOwnProperty(l) && (r[l] = n(e[l], t)); return r; case 'Array': return ((a = C.util.objId(e)), t[a]? t[a]: ((r = []),(t[a] = r), e.forEach(function (e, a) { r[a] = n(e, t);}), r)); default: return e;}}}, languages: { extend: function (e, a) { var n = C.util.clone(C.languages[e]); for (var t in a) n[t] = a[t]; return n;}, insertBefore: function (n, e, a, t) { var r = (t = t || C.languages)[n], i = {}; for (var l in r) if (r.hasOwnProperty(l)) { if (l == e) for (var o in a) a.hasOwnProperty(o) && (i[o] = a[o]); a.hasOwnProperty(l) || (i[l] = r[l]);} var s = t[n]; return ((t[n] = i), C.languages.DFS(C.languages, function (e, a) { a === s && e != n && (this[e] = i);}), i);}, DFS: function e(a, n, t, r) { r = r || {}; var i = C.util.objId; for (var l in a) if (a.hasOwnProperty(l)) { n.call(a, l, a[l], t || l); var o = a[l], s = C.util.type(o);'Object' !== s || r[i(o)] ? 'Array' !== s || r[i(o)] || ((r[i(o)] = !0), e(o, n, l, r)) : ((r[i(o)] = !0), e(o, n, null, r));}}}, plugins: {}, highlightAll: function (e, a) { C.highlightAllUnder(document, e, a);}, highlightAllUnder: function (e, a, n) { var t = { callback: n, selector: 'code[class_="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'}; C.hooks.run('before-highlightall', t); for (var r, i = t.elements || e.querySelectorAll(t.selector), l = 0; (r = i[l++]); ) C.highlightElement(r, !0 === a, t.callback);}, highlightElement: function (e, a, n) { for (var t, r = 'none', i = e; i && !c.test(i.className); ) i = i.parentNode; i && ((r = (i.className.match(c) || [, 'none'])[1].toLowerCase()), (t = C.languages[r])),(e.className = e.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r), e.parentNode &&((i = e.parentNode), /pre/i.test(i.nodeName) && (i.className = i.className.replace(c, '').replace(/\s+/g, ' ') + ' language-' + r)); var l = { element: e, language: r, grammar: t, code: e.textContent }, o = function (e) {(l.highlightedCode = e), C.hooks.run('before-insert', l),(l.element.innerHTML = l.highlightedCode), C.hooks.run('after-highlight', l), C.hooks.run('complete', l), n && n.call(l.element);}; if ((C.hooks.run('before-sanity-check', l), l.code)) if ((C.hooks.run('before-highlight', l), l.grammar)) if (a && g.Worker) { var s = new Worker(C.filename);(s.onmessage = function (e) { o(e.data);}), s.postMessage( JSON.stringify({ language: l.language, code: l.code, immediateClose: !0}));} else o(C.highlight(l.code, l.grammar, l.language)); else o(C.util.encode(l.code)); else C.hooks.run('complete', l);}, highlight: function (e, a, n) { var t = { code: e, grammar: a, language: n }; return ( C.hooks.run('before-tokenize', t),(t.tokens = C.tokenize(t.code, t.grammar)), C.hooks.run('after-tokenize', t), M.stringify(C.util.encode(t.tokens), t.language));}, matchGrammar: function (e, a, n, t, r, i, l) { for (var o in n) if (n.hasOwnProperty(o) && n[o]) { if (o == l) return; var s = n[o]; s = 'Array' === C.util.type(s) ? s : [s]; for (var g = 0; g < s.length; ++g) { var c = s[g], u = c.inside, h = !!c.lookbehind, f = !!c.greedy, d = 0, m = c.alias; if (f && !c.pattern.global) { var p = c.pattern.toString().match(/[imuy]_$/)[0]; c.pattern = RegExp(c.pattern.source, p + 'g');} c = c.pattern || c; for (var y = t, v = r; y < a.length; v += a[y].length, ++y) { var k = a[y]; if (a.length > e.length) return; if (!(k instanceof M)) { if (f && y != a.length - 1) { if (((c.lastIndex = v), !(x = c.exec(e)))) break; for ( var b = x.index + (h ? x[1].length : 0), w = x.index + x[0].length, A = y, P = v, O = a.length; A < O && (P < w || (!a[A].type && !a[A - 1].greedy));++A)(P += a[A].length) <= b && (++y, (v = P)); if (a[y] instanceof M) continue;(N = A - y), (k = e.slice(v, P)), (x.index -= v);} else { c.lastIndex = 0; var x = c.exec(k), N = 1;} if (x) { h && (d = x[1] ? x[1].length : 0); w = (b = x.index + d) + (x = x[0].slice(d)).length; var j = k.slice(0, b), S = k.slice(w), E = [y, N]; j && (++y, (v += j.length), E.push(j)); var * = new M(o, u ? C.tokenize(x, u) : x, m, x, f); if ((E.push(*), S && E.push(S), Array.prototype.splice.apply(a, E), 1 != N && C.matchGrammar(e, a, n, y, v, !0, o), i)) break;} else if (i) break;}}}}}, tokenize: function (e, a) { var n = [e], t = a.rest; if (t) { for (var r in t) a[r] = t[r]; delete a.rest;} return C.matchGrammar(e, n, a, 0, 0, !1), n;}, hooks: { all: {}, add: function (e, a) { var n = C.hooks.all;(n[e] = n[e] || []), n[e].push(a);}, run: function (e, a) { var n = C.hooks.all[e]; if (n && n.length) for (var t, r = 0; (t = n[r++]); ) t(a);}}, Token: M}; function M(e, a, n, t, r) {(this.type = e), (this.content = a), (this.alias = n), (this.length = 0 | (t || '').length), (this.greedy = !!r);} if (((g.Prism = C),(M.stringify = function (e, a) { if ('string' == typeof e) return e; if (Array.isArray(e)) return e.map(function (e) { return M.stringify(e, a);}).join(''); var n = { type: e.type, content: M.stringify(e.content, a), tag: 'span', classes: ['token', e.type], attributes: {}, language: a}; if (e.alias) { var t = Array.isArray(e.alias) ? e.alias : [e.alias]; Array.prototype.push.apply(n.classes, t);} C.hooks.run('wrap', n); var r = Object.keys(n.attributes).map(function (e) { return e + '="' + (n.attributes[e] || '').replace(/"/g, '"') + '"';}).join(' '); return '<' + n.tag + ' class="' + n.classes.join(' ') + '"' + (r ? ' ' + r : '') + '>' + n.content + '</' + n.tag + '>';}),!g.document)) return ( g.addEventListener &&(C.disableWorkerMessageHandler || g.addEventListener('message', function (e) { var a = JSON.parse(e.data), n = a.language, t = a.code, r = a.immediateClose; g.postMessage(C.highlight(t, C.languages[n], n)), r && g.close();},!1)), C); var e = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); return ( e &&((C.filename = e.src), C.manual || e.hasAttribute('data-manual') ||('loading' !== document.readyState? window.requestAnimationFrame? window.requestAnimationFrame(C.highlightAll): window.setTimeout(C.highlightAll, 16): document.addEventListener('DOMContentLoaded', C.highlightAll))), C);})(_self);'undefined' != typeof module && module.exports && (module.exports = Prism), 'undefined' != typeof global && (global.Prism = Prism);(Prism.languages.markup = { comment: //, prolog: /<?[\s\S]+??>/, doctype: /<!DOCTYPE[\s\S]+?>/i, cdata: /<![CDATA[[\s\S]_?]]>/i, tag: { pattern: /</?(?!\d)\s>\/=$<%+(?:\s(?:\s\s>\/=+(?:\s=\s(?:"""|'' _'|\s'">=+(?=[\s>]))|(?=[\s/>])))+)?\s*/?>/i, greedy: !0, inside: { tag: { pattern: /^</?\s>\/+/i, inside: { punctuation: /^</?/, namespace: /^\s>\/:+:/ }},'attr-value': { pattern: /=\s*(?:"""|'''|\s'">=+)/i, inside: { punctuation: [/^=/, { pattern: /^(\s*)["']|["']$/, lookbehind: !0 }] } }, punctuation: /\/?>/, 'attr-name': { pattern: /[^\s>\/]+/, inside: { namespace: /^[^\s>\/:]+:/ } } } }, entity: /&#?[\da-z]{1,8};/i }),(Prism.languages.markup.tag.inside['attr-value'].inside.entity = Prism.languages.markup.entity), Prism.hooks.add('wrap', function (a) { 'entity' === a.type && (a.attributes.title = a.content.replace(/&amp;/, '&')); }), Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { value: function (a, e) { var s = {}; (s['language-' + e] = { pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, lookbehind: !0, inside: Prism.languages[e]}),(s.cdata = /^<![CDATA[|]]>$/i); var n = {'included-cdata': { pattern: /<![CDATA[[\s\S]*?]]>/i, inside: s }}; n['language-' + e] = { pattern: /[\s\S]+/, inside: Prism.languages[e] }; var i = {};(i[a] = { pattern: RegExp('(<[\s\S]?>)(?:<!\[CDATA\[[\s\S]?\]\]>\s|[\s\S])?(?=<\/>)'.replace(/**/g, a), 'i'), lookbehind: !0, greedy: !0, inside: n}), Prism.languages.insertBefore('markup', 'cdata', i);}}),(Prism.languages.xml = Prism.languages.extend('markup', {})),(Prism.languages.html = Prism.languages.markup),(Prism.languages.mathml = Prism.languages.markup),(Prism.languages.svg = Prism.languages.markup);!(function (s) { var t = /("|')(?:\(?:\r\n|[\s\S])|(?!\1)\\\r\n)_\1/;(s.languages.css = { comment: //*[\s\S]_?*//, atrule: { pattern: /@[\w-]+[\s\S]?(?:;|(?=\s{))/, inside: { rule: /@[\w-]+/ }}, url: { pattern: RegExp('url\((?:' + t.source + '|\n\r() _)\)', 'i'), inside: { function: /^url/i, punctuation: /^(|)$/ }}, selector: RegExp('^{}\s, string: { pattern: t, greedy: !0 }, property: /[-_a-z\xA0-\uFFFF][-\w\xa0-\uffff](?=\s:)/i, important: /!important\b/i, function: /[-a-z0-9]+(?=()/i, punctuation: /[(){};:,]/}),(s.languages.css.atrule.inside.rest = s.languages.css); var e = s.languages.markup; e &&(e.tag.addInlined('style', 'css'), s.languages.insertBefore('inside','attr-value',{'style-attr': { pattern: /\s
    https://bgoonz-blog.netlify.app/images/code.png
  • Web Dev Hub
    Docs Go To Sitemap: Go Now --> Actual Docs: <div id="search" /> Docs Gitpod Docs Doc Websites & Repos Python Practice Lambda Bootcamp Website React Notes Project Showcase Data Structures & Algorithms Lambda Site Static Content Server Mini-Project Showcase Useful Snippets Markdown Templates Zumzi Video Conferencing App (mesibo api backend)
    https://bgoonz-blog.netlify.app/images/code.png
  • Blog
    Blog Exclusive Blog Content November 24, 2021 Es6 Features lorem-ipsum Read more October 14, 2021 flow-control-in-python lorem-ipsum Read more October 14, 2021 Functions in Python wubalubadubdub Read more September 30, 2021 Awesome GraphQL lorem-ipsum Read more September 30, 2021 Netlify CMS Reference Sheet lorem-ipsum Read more September 30, 2021 Web Development Tools lorem-ipsum Read more September 14, 2021 Leetcode (Data Structures) A guide to computational complexity Read more September 11, 2021 Big O Computational Complexity Bubble sort, sorts an array of integers by bubbling the largest integer to the top. Read more September 11, 2021 Javascript Interview Questions What are the possible ways to create objects in JavaScript Read more September 02, 2021 Git Bash lorem-ipsum Read more July 26, 2021 Blog Archive Blog Archive Read more July 26, 2021 ExpressJS Apis## **Overview** A **database schema** is the shape of our database. It defines what tables we'll have, which columns should exist within the tables and any restrictions on each column. A well-designed database schema keeps the data well organized and can help ensure high-quality data. Note that while schema design is usually left to Database Administrators (DBAs), understanding schema helps when designing APIs and database logic. And in a smaller team, this step may fall on the developer. Read more July 26, 2021 Webscraping w nodejs June 03, 2021 Python Resources June 03, 2021 Python Resources May 23, 2021 Netlify CMS Intro
    https://bgoonz-blog.netlify.app/images/5.jpg
  • Web-Dev-Hub
    Close Menu Tutorials This section is dedicated to coding walkthroughs: Enviorment Setup Tutorial Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Tools
    Tools PDF Tools Markdown tools Number Base Converter Text Tools Other Tools Awesome Search Paste excel to HTML Cloud Storage Up to 1TB of cloud Storage for file sharing! Text Tools Ternary Converter Github HTML Render from link Form Builder GUI See the Pen Simple Typing Carousel by Bryan C Guner (@bgoonz) on CodePen. Data Structures General Utilities Archive md and html
    https://bgoonz-blog.netlify.app/images/tex.PNG
  • Web-Dev-Hub
    Tips Lorem ipsum Tips lorem-ipsum
    https://bgoonz-blog.netlify.app/images/code.png
  • Web Dev Hub
    Navigation✅HOME🌍✅blog/🌍✅blog/awesome-graphql/🌍✅blog/big-o-complexity/🌍✅blog/blog-archive/🌍✅blog/blogwcomments/🌍✅blog/data-structures/🌍✅blog/git-gateway/🌍✅blog/interview-questions-js/🌍✅blog/my-medium/🌍✅blog/netlify-cms/🌍✅blog/platform-docs/🌍✅blog/python-for-js-dev/🌍✅blog/python-resources/🌍✅blog/web-dev-trends/🌍✅blog/web-scraping/🌍✅⇒🌍✅⇒about/🌍✅⇒about/eng-portfolio/🌍✅⇒about/intrests/🌍✅⇒about/job-search/🌍✅⇒about/resume/🌍✅⇒articles/🌍✅⇒articles/basic-web-dev/🌍✅⇒articles/buffers/🌍✅⇒articles/dev-dep/🌍✅⇒articles/event-loop/🌍✅⇒articles/fs-module/🌍✅⇒articles/how-the-web-works/🌍✅⇒articles/http/🌍✅⇒articles/install/🌍✅⇒articles/intro/🌍✅⇒articles/module-exports/🌍✅⇒articles/node-api-express/🌍✅⇒articles/node-cli-args/🌍✅⇒articles/node-common-modules/🌍✅⇒articles/node-env-variables/🌍✅⇒articles/node-js-language/🌍✅⇒articles/node-package-manager/🌍✅⇒articles/node-repl/🌍✅⇒articles/node-run-cli/🌍✅⇒articles/nodejs/🌍✅⇒articles/nodevsbrowser/🌍✅⇒articles/npm/🌍✅⇒articles/npx/🌍✅⇒articles/os-module/🌍✅⇒articles/reading-files/🌍✅⇒articles/semantic-html/🌍✅⇒articles/semantic/🌍✅⇒articles/the-uniform-resource-locator-(url)/🌍✅⇒articles/understanding-firebase/🌍✅⇒articles/v8/🌍✅⇒articles/web-standards-checklist/🌍✅⇒articles/webdev-tools/🌍✅⇒articles/writing-files/🌍✅⇒audio/🌍✅⇒audio/dfft/🌍✅⇒audio/discrete-fft/🌍✅⇒audio/dtw-python-explained/🌍✅⇒audio/dynamic-time-warping/🌍✅⇒community/🌍✅⇒community/video-chat/🌍✅⇒content/🌍✅⇒content/algo/🌍✅⇒content/archive/🌍✅⇒content/data-structures-algo/🌍✅⇒content/gatsby-queries-mutations/🌍✅⇒content/history-api/🌍✅⇒content/js-async-n-callbacks/🌍✅⇒content/projects/🌍✅⇒content/recent-projects/🌍✅⇒content/trouble-shooting/🌍✅⇒docs/🌍✅⇒docs/appendix/🌍✅⇒docs/await-keyword/🌍✅⇒docs/bash/🌍✅⇒docs/content/🌍✅⇒docs/css/🌍✅⇒docs/data-structures-docs/🌍✅⇒docs/git-repos/🌍✅⇒docs/no-whiteboarding/🌍✅⇒docs/regex-in-js/🌍✅⇒docs/sitemap/🌍✅⇒faq/🌍✅⇒faq/contact/🌍✅⇒faq/plug-ins/🌍✅⇒gallery/🌍✅⇒interact/🌍✅⇒interact/callstack-visual/🌍✅⇒interact/clock/🌍✅⇒interact/jupyter-notebooks/🌍✅⇒interact/other-sites/🌍✅⇒interact/video-chat/🌍✅⇒javascript/🌍✅⇒javascript/bigo/🌍✅⇒javascript/constructor-functions/🌍✅⇒medium/🌍✅⇒medium/medium-links/🌍✅⇒medium/my-websites/🌍✅⇒python/🌍✅⇒python/at-length/🌍✅⇒python/google-sheets-api/🌍✅⇒python/python-ds/🌍✅⇒python/snippets/🌍✅⇒quick-reference/🌍✅⇒quick-reference/awesome-lists/🌍✅⇒quick-reference/awesome-static/🌍✅⇒quick-reference/create-react-app/🌍✅⇒quick-reference/emmet/🌍✅⇒quick-reference/git-bash/🌍✅⇒quick-reference/github-search/🌍✅⇒quick-reference/google-firebase/🌍✅⇒quick-reference/heroku-error-codes/🌍✅⇒quick-reference/installation/🌍✅⇒quick-reference/minifiction/🌍✅⇒quick-reference/new-repo-instructions/🌍✅⇒quick-reference/notes-template/🌍✅⇒quick-reference/psql-setup/🌍✅⇒quick-reference/psql/🌍✅⇒quick-reference/pull-request-rubric/🌍✅⇒quick-reference/quick-links/🌍✅⇒quick-reference/resources/🌍✅⇒quick-reference/toprepos/🌍✅⇒quick-reference/understanding-path/🌍✅⇒quick-reference/vscode-themes/🌍✅⇒quick-reference/vscode/🌍✅⇒react/🌍✅⇒react/createreactapp/🌍✅⇒react/react-docs/🌍✅⇒react/react-in-depth/🌍✅⇒react/react2/🌍✅⇒sitemap/🌍✅⇒tools/🌍✅⇒tools/cloudstorage/🌍✅⇒tools/data-structures/🌍✅⇒tools/dev-utilities/🌍✅⇒tools/markdown-html/🌍✅⇒tools/more-tools/🌍✅review/🌍[✅showcase/🌍] https://bgoonz-blog.netlify.app/showcase/)🌍⇒https://bgoonz-blog.netlify.app/🗺️🌍⇒blog🗺️🌍⇒docs🗺️🌍⇒readme🗺️🌍⇒review🗺️🌍⇒showcase🗺️🌍⇒blog/awesome-graphql🗺️🌍⇒blog/big-o-complexity🗺️🌍⇒blog/blog-archive🗺️🌍⇒blog/blogwcomments🗺️🌍⇒blog/data-structures🗺️🌍⇒blog/flow-control-in-python🗺️🌍⇒blog/functions-in-python🗺️🌍⇒blog/git-gateway🗺️🌍⇒blog/interview-questions-js🗺️🌍⇒blog/media-queries-explained🗺️🌍⇒blog/my-medium🗺️🌍⇒blog/netlify-cms🗺️🌍⇒blog/platform-docs🗺️🌍⇒blog/python-for-js-dev🗺️🌍⇒blog/python-resources🗺️🌍⇒blog/web-dev-trends🗺️🌍⇒blog/web-scraping🗺️🌍⇒docs/about🗺️🌍⇒docs/articles🗺️🌍⇒docs/audio🗺️🌍⇒docs/career🗺️🌍⇒docs/community🗺️🌍⇒docs/content🗺️🌍⇒docs/docs🗺️🌍⇒docs/faq🗺️🌍⇒docs/gallery🗺️🌍⇒docs/interact🗺️🌍⇒docs/javascript🗺️🌍⇒docs/leetcode🗺️🌍⇒docs/other-content🗺️🌍⇒docs/privacy-policy🗺️🌍⇒docs/projects🗺️🌍⇒docs/python🗺️🌍⇒docs/quick-reference🗺️🌍⇒docs/react🗺️🌍⇒docs/reference🗺️🌍⇒docs/search🗺️🌍⇒docs/sitemap🗺️🌍⇒docs/tools🗺️🌍⇒docs/tutorials🗺️🌍⇒docs/about/eng-portfolio🗺️🌍⇒docs/about/ideas-for-this-website🗺️🌍⇒docs/about/intrests🗺️🌍⇒docs/about/job-search🗺️🌍⇒docs/about/resume🗺️🌍⇒docs/articles/basic-web-dev🗺️🌍⇒docs/articles/buffers🗺️🌍⇒docs/articles/dev-dep🗺️🌍⇒docs/articles/event-loop🗺️🌍⇒docs/articles/fs-module🗺️🌍⇒docs/articles/how-the-web-works🗺️🌍⇒docs/articles/http🗺️🌍⇒docs/articles/install🗺️🌍⇒docs/articles/intro🗺️🌍⇒docs/articles/media-queries-no-more🗺️🌍⇒docs/articles/module-exports🗺️🌍⇒docs/articles/nextjs🗺️🌍⇒docs/articles/node-api-express🗺️🌍⇒docs/articles/node-cli-args🗺️🌍⇒docs/articles/node-common-modules🗺️🌍⇒docs/articles/node-env-variables🗺️🌍⇒docs/articles/node-js-language🗺️🌍⇒docs/articles/node-package-manager🗺️🌍⇒docs/articles/node-repl🗺️🌍⇒docs/articles/node-run-cli🗺️🌍⇒docs/articles/nodejs🗺️🌍⇒docs/articles/nodevsbrowser🗺️🌍⇒docs/articles/npm🗺️🌍⇒docs/articles/npx🗺️🌍⇒docs/articles/os-module🗺️🌍⇒docs/articles/package-lock🗺️🌍⇒docs/articles/reading-files🗺️🌍⇒docs/articles/semantic🗺️🌍⇒docs/articles/semantic-html🗺️🌍⇒docs/articles/the-uniform-resource-locator-(url)🗺️🌍⇒docs/articles/understanding-firebase🗺️🌍⇒docs/articles/v8🗺️🌍⇒docs/articles/web-standards-checklist🗺️🌍⇒docs/articles/webdev-tools🗺️🌍⇒docs/articles/write-2-json-with-python🗺️🌍⇒docs/articles/writing-files🗺️🌍⇒docs/audio/audio🗺️🌍⇒docs/audio/audio-feature-extraction🗺️🌍⇒docs/audio/dfft🗺️🌍⇒docs/audio/discrete-fft🗺️🌍⇒docs/audio/dtw-python-explained🗺️🌍⇒docs/audio/dynamic-time-warping🗺️🌍⇒docs/audio/web-audio-api🗺️🌍⇒docs/career/confidence🗺️🌍⇒docs/career/dev-interview🗺️🌍⇒docs/career/interview-dos-n-donts🗺️🌍⇒docs/career/job-boards🗺️🌍⇒docs/community/an-open-letter-2-future-developers🗺️🌍⇒docs/community/video-chat🗺️🌍⇒docs/content/algo🗺️🌍⇒docs/content/archive🗺️🌍⇒docs/content/data-structures-algo🗺️🌍⇒docs/content/gatsby-Queries-Mutations🗺️🌍⇒docs/content/history-api🗺️🌍⇒docs/content/projects🗺️🌍⇒docs/content/recent-projects🗺️🌍⇒docs/content/trouble-shooting🗺️🌍⇒docs/docs/appendix🗺️🌍⇒docs/docs/bash🗺️🌍⇒docs/docs/content🗺️🌍⇒docs/docs/css🗺️🌍⇒docs/docs/data-structures-docs🗺️🌍⇒docs/docs/git-reference🗺️🌍⇒docs/docs/git-repos🗺️🌍⇒docs/docs/html-spec🗺️🌍⇒docs/docs/markdown🗺️🌍⇒docs/docs/no-whiteboarding🗺️🌍⇒docs/docs/node-docs-complete🗺️🌍⇒docs/docs/node-docs-full🗺️🌍⇒docs/docs/regex-in-js🗺️🌍⇒docs/docs/sitemap🗺️🌍⇒docs/faq/contact🗺️🌍⇒docs/faq/plug-ins🗺️🌍⇒docs/interact/callstack-visual🗺️🌍⇒docs/interact/clock🗺️🌍⇒docs/interact/jupyter-notebooks🗺️🌍⇒docs/interact/other-sites🗺️🌍⇒docs/interact/video-chat🗺️🌍⇒docs/javascript/arrow-functions🗺️🌍⇒docs/javascript/await-keyword🗺️🌍⇒docs/javascript/bigo🗺️🌍⇒docs/javascript/clean-code🗺️🌍⇒docs/javascript/constructor-functions🗺️🌍⇒docs/javascript/promises🗺️🌍⇒docs/javascript/review🗺️🌍⇒docs/javascript/this-is-about-this🗺️🌍⇒docs/projects/medium-links🗺️🌍⇒docs/projects/my-websites🗺️🌍⇒docs/python/at-length🗺️🌍⇒docs/python/basics🗺️🌍⇒docs/python/cheat-sheet🗺️🌍⇒docs/python/comprehensive-guide🗺️🌍⇒docs/python/examples🗺️🌍⇒docs/python/flow-control🗺️🌍⇒docs/python/functions🗺️🌍⇒docs/python/google-sheets-api🗺️🌍⇒docs/python/intro-for-js-devs🗺️🌍⇒docs/python/python-ds🗺️🌍⇒docs/python/snippets🗺️🌍⇒docs/quick-reference/Emmet🗺️🌍⇒docs/quick-reference/all-emojis🗺️🌍⇒docs/quick-reference/create-react-app🗺️🌍⇒docs/quick-reference/git-bash🗺️🌍⇒docs/quick-reference/git-tricks🗺️🌍⇒docs/quick-reference/google-firebase🗺️🌍⇒docs/quick-reference/heroku-error-codes🗺️🌍⇒docs/quick-reference/installation🗺️🌍⇒docs/quick-reference/markdown-dropdowns🗺️🌍⇒docs/quick-reference/minifiction🗺️🌍⇒docs/quick-reference/new-repo-instructions🗺️🌍⇒docs/quick-reference/psql-setup🗺️🌍⇒docs/quick-reference/pull-request-rubric🗺️🌍⇒docs/quick-reference/quick-links🗺️🌍⇒docs/quick-reference/topRepos🗺️🌍⇒docs/quick-reference/understanding-path🗺️🌍⇒docs/quick-reference/vscode-themes🗺️🌍⇒docs/react/cheatsheet🗺️🌍⇒docs/react/createReactApp🗺️🌍⇒docs/react/demo🗺️🌍⇒docs/react/jsx🗺️🌍⇒docs/react/react-docs🗺️🌍⇒docs/react/react-in-depth🗺️🌍⇒docs/react/react2🗺️🌍⇒docs/react/render-elements🗺️🌍⇒docs/reference/awesome-lists🗺️🌍⇒docs/reference/awesome-static🗺️🌍⇒docs/reference/bookmarks🗺️🌍⇒docs/reference/embed-the-web🗺️🌍⇒docs/reference/github-search🗺️🌍⇒docs/reference/how-2-reinstall-npm🗺️🌍⇒docs/reference/how-to-kill-a-process🗺️🌍⇒docs/reference/installing-node🗺️🌍⇒docs/reference/intro-to-nodejs🗺️🌍⇒docs/reference/notes-template🗺️🌍⇒docs/reference/psql🗺️🌍⇒docs/reference/resources🗺️🌍⇒docs/reference/vscode🗺️🌍⇒docs/reference/web-api's🗺️🌍⇒docs/tools/data-structures🗺️🌍⇒docs/tools/dev-utilities🗺️🌍⇒docs/tools/google-cloud🗺️🌍⇒docs/tools/markdown-html🗺️🌍⇒docs/tools/more-tools🗺️🌍⇒docs/tutorials/google-lighthouse-cli🗺️
    https://bgoonz-blog.netlify.app/images/background.gif
  • Web-Dev-Hub
    lorem-ipsum Search: Actual Docs: Docs
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Reference Reference:[SITEMAP🗺🟈]( https://bgoonz-blog.netlify.app/docs/sitemap/) Bookmarks: SearchAwesome: lorem-ipsum Awesome Static Site Resources Kill a Process in Linux How To Reinstall NPM and Node.js On Your System Installing Node Intro To NodeJS Postgresql Cheat Sheet Developer Resources Web Apis Web Dev Bookmarks Google Cloud Github Search Awesome Lists Notes Template vscode
    https://bgoonz-blog.netlify.app/images/code.png
  • React
    React React Examples: ### For more resources visit: bgoonz/React Notes V3A JavaScript library for building user interfaces React makes it painless to create interactive UIs. Design simple…github.com Use this appendix to get any prerequisite concepts and terminology under your belt: Here I will walk through a demo…. skip down below for more fundamental examples and resources… Learn Redux: ALL CODE: React Cheat Sheet: React-Tutorial-1: react-tutorial-1A React repl by bgoonzreplit.com React Boilerplate: React.js + Babel + Webpack BoilerplateCreated by @eankeen | The ultimate trifecta - React, Babel, and Webpack - complete with hot module reloading and a…replit.com React Cheat Sheets: React Class Components Demo Rendering Elements With React Introducing JSX React In Depth Intro To React Bash-Commands npx-create-react-app React Docs
    https://bgoonz-blog.netlify.app/images/code.png
  • Cheat Sheets
    QuickRef Quick Reference Markdown Dropdown Git Tricks Git Bash All Emojis Heroku Error Codes Pull Request Template PostgreSQL Setup Quick Links Understanding PATH Firebase (Firebasics) Installation How To Minify Code For Better Web Performance Top Repos new-repo-git Emmet Cheat Sheet Getting Started W Create React App vscode-themes
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Python Python Resources My Python Docs: My Python Website Python Study Guide for a JavaScript Programmer A guide to commands in Python from what you know in JavaScript Python Study Guide for a JavaScript Programmer### Applications of Tutorial & Cheat Sheet Respectivley (At Bottom Of Tutorial): Basics PEP8 : Python Enhancement Proposals, style-guide for Python. print is the equivalent of console.log.'print() == console.log()'# is used to make comments in your code. def foo(): """ The foo function does many amazing things that you should not question. Just accept that it exists and use it with caution. """ secretThing() Python has a built in help function that let's you see a description of the source code without having to navigate to it… “-SickNasty … Autor Unknown” Numbers Python has three types of numbers: Integer Positive and Negative Counting Numbers. No Decimal Point Created by a literal non-decimal point number … or … with the int() constructor. print(3) # => 3 print(int(19)) # => 19 print(int()) # => 0 3. Complex Numbers Consist of a real part and imaginary part. Boolean is a subtype of integer in Python.🤷‍♂️ If you came from a background in JavaScript and learned to accept the premise(s) of the following meme… Than I am sure you will find the means to suspend your disbelief. print(2.24) # => 2.24 print(2.) # => 2.0 print(float()) # => 0.0 print(27e-5) # => 0.00027 KEEP IN MIND: The i is switched to a j in programming. T*his is because the letter i is common place as the de facto index for any and all enumerable entities so it just makes sense not to compete for name-* space when there's another 25 letters that don't get used for every loop under the sun. My most medium apologies to Leonhard Euler. print(7j) # => 7j print(5.1+7.7j)) # => 5.1+7.7j print(complex(3, 5)) # => 3+5j print(complex(17)) # => 17+0j print(complex()) # => 0j Type Casting : The process of converting one number to another.# Using Float print(17) # => 17 print(float(17)) # => 17.0 # Using Int print(17.0) # => 17.0 print(int(17.0)) # => 17 # Using Str print(str(17.0) + ' and ' + str(17)) # => 17.0 and 17 The arithmetic operators are the same between JS and Python, with two additions:“**” : Double asterisk for exponent.“//” : Integer Division. There are no spaces between math operations in Python. Integer Division gives the other part of the number from Module; it is a way to do round down numbers replacing Math.floor() in JS. There are no ++ and -- in Python, the only shorthand operators are: Strings Python uses both single and double quotes. You can escape strings like so 'Jodi asked, "What\'s up, Sam?"' Multiline strings use triple quotes. print('''My instructions are very long so to make them more readable in the code I am putting them on more than one line. I can even include "quotes" of any kind because they won't get confused with the end of the string!''') Use the len() function to get the length of a string. print(len(“Spaghetti”)) # => 9 Python uses zero-based indexing Python allows negative indexing (thank god!) print(“Spaghetti”[-1]) # => i print(“Spaghetti”[-4]) # => e Python let's you use ranges You can think of this as roughly equivalent to the slice method called on a JavaScript object or string… (mind you that in JS … strings are wrapped in an object (under the hood)… upon which the string methods are actually called. As a immutable privative type *by textbook definition**, a string literal could not hope to invoke most of it's methods without violating the state it was bound to on initialization if it were not for this bit of syntactic sugar.)* print(“Spaghetti”[1:4]) # => pag print(“Spaghetti”[4:-1]) # => hett print(“Spaghetti”[4:4]) # => (empty string) The end range is exclusive just like slice in JS.# Shortcut to get from the beginning of a string to a certain index. print("Spaghetti"[:4]) # => Spag print("Spaghetti"[:-1]) # => Spaghett # Shortcut to get from a certain index to the end of a string. print("Spaghetti"[1:]) # => paghetti print("Spaghetti"[-4:]) # => etti The index string function is the equiv. of indexOf() in JS print("Spaghetti".index("h")) # => 4 print("Spaghetti".index("t")) # => 6 The count function finds out how many times a substring appears in a string… pretty nifty for a hard coded feature of the language. print("Spaghetti".count("h")) # => 1 print("Spaghetti".count("t")) # => 2 print("Spaghetti".count("s")) # => 0 print('''We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too. '''.count('the ')) # => 4 You can use + to concatenate strings, just like in JS. You can also use “*” to repeat strings or multiply strings. Use the format() function to use placeholders in a string to input values later on. first_name = "Billy" last_name = "Bob" print('Your name is {0} {1}'.format(first_name, last_name)) # => Your name is Billy Bob Shorthand way to use format function is: _`print(f'Your name is {first name} {last_name}')` Some useful string methods. Note that in JS join is used on an Array, in Python it is used on String.- There are also many handy testing methods. Variables and Expressions Duck-Typing : Programming Style which avoids checking an object's type to figure out what it can do. Duck Typing is the fundamental approach of Python. Assignment of a value automatically declares a variable. a = 7 b = 'Marbles' print(a) # => 7 print(b) # => Marbles You can chain variable assignments to give multiple var names the same value. Use with caution as this is highly unreadable count = max = min = 0 print(count) # => 0 print(max) # => 0 print(min) # => 0 The value and type of a variable can be re-assigned at any time. a = 17 print(a) # => 17 a = 'seventeen' print(a) # => seventeen NaN _does not exist in Python, but you can 'create' it like so: _ print(float("nan")) Python replaces null with none. none is an object and can be directly assigned to a variable. Using none is a convenient way to check to see why an action may not be operating correctly in your program. Boolean Data Type One of the biggest benefits of Python is that it reads more like English than JS does.# Logical AND print(True and True) # => True print(True and False) # => False print(False and False) # => False # Logical OR print(True or True) # => True print(True or False) # => True print(False or False) # => False # Logical NOT print(not True) # => False print(not False and True) # => True print(not True or False) # => False By default, Python considers an object to be true UNLESS it is one of the following: Constant None or False Zero of any numeric type. Empty Sequence or Collection. True and False must be capitalized Comparison Operators Python uses all the same equality operators as JS. In Python, equality operators are processed from left to right. Logical operators are processed in this order: NOT AND OR Just like in JS, you can use parentheses to change the inherent order of operations. Short Circuit : Stopping a program when a true or false has been reached. Identity vs Equality print (2 == '2') # => False print (2 is '2') # => False print ("2" == '2') # => True print ("2" is '2') # => True # There is a distinction between the number types. print (2 == 2.0) # => True print (2 is 2.0) # => False In the Python community it is better to use is and is not over == or != If Statements if name == 'Monica': print('Hi, Monica.') if name == 'Monica': print('Hi, Monica.') else: print('Hello, stranger.') if name == 'Monica': print('Hi, Monica.') elif age < 12: print('You are not Monica, kiddo.') elif age > 2000: print('Unlike you, Monica is not an undead, immortal vampire.') elif age > 100: print('You are not Monica, grannie.') Remember the order of elif statements matter. While Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 Break statement also exists in Python. spam = 0 while True: print('Hello, world.') spam = spam + 1 if spam >= 5: break As are continue statements spam = 0 while True: print('Hello, world.') spam = spam + 1 if spam < 5: continue break Try/Except Statements Python equivalent to try/catch a = 321 try: print(len(a)) except: print('Silently handle error here') # Optionally include a correction to the issue a = str(a) print(len(a) a = '321' try: print(len(a)) except: print('Silently handle error here') # Optionally include a correction to the issue a = str(a) print(len(a)) You can name an error to give the output more specificity. a = 100 b = 0 try: c = a / b except ZeroDivisionError: c = None print(c) You can also use the pass commmand to by pass a certain error. a = 100 b = 0 try: print(a / b) except ZeroDivisionError: pass The pass method won't allow you to bypass every single error so you can chain an exception series like so: a = 100 # b = "5" try: print(a / b) except ZeroDivisionError: pass except (TypeError, NameError): print("ERROR!") You can use an else statement to end a chain of except statements.# tuple of file names files = ('one.txt', 'two.txt', 'three.txt') # simple loop for filename in files: try: # open the file in read mode f = open(filename, 'r') except OSError: # handle the case where file does not exist or permission is denied print('cannot open file', filename) else: # do stuff with the file object (f) print(filename, 'opened successfully') print('found', len(f.readlines()), 'lines') f.close() finally is used at the end to clean up all actions under any circumstance. def divide(x, y): try: result = x / y except ZeroDivisionError: print("Cannot divide by zero") else: print("Result is", result) finally: print("Finally...") Using duck typing to check to see if some value is able to use a certain method.# Try a number - nothing will print out a = 321 if hasattr(a, '__len__'): print(len(a)) # Try a string - the length will print out (4 in this case) b = "5555" if hasattr(b, '__len__'): print(len(b)) Pass Pass Keyword is required to write the JS equivalent of : if (true) { } while (true) {} if True: pass while True: pass Functions Function definition includes: The def keyword The name of the function A list of parameters enclosed in parentheses. A colon at the end of the line. One tab indentation for the code to run. You can use default parameters just like in JS def greeting(name, saying="Hello"): print(saying, name) greeting("Monica") # Hello Monica greeting("Barry", "Hey") # Hey Barry Keep in mind, default parameters must always come after regular parameters.# THIS IS BAD CODE AND WILL NOT RUN def increment(delta=1, value): return delta + value You can specify arguments by name without destructuring in Python. def greeting(name, saying="Hello"): print(saying, name) # name has no default value, so just provide the value # saying has a default value, so use a keyword argument greeting("Monica", saying="Hi") The lambda keyword is used to create anonymous functions and are supposed to be one-liners. toUpper = lambda s: s.upper() Notes Formatted Strings Remember that in Python join() is called on a string with an array/list passed in as the argument. Python has a very powerful formatting engine. format() is also applied directly to strings. shopping_list = ['bread','milk','eggs'] print(','.join(shopping_list)) Comma Thousands Separator print('{:,}'.format(1234567890)) '1,234,567,890' Date and Time d = datetime.datetime(2020, 7, 4, 12, 15, 58) print('{:%Y-%m-%d %H:%M:%S}'.format(d)) '2020–07–04 12:15:58' Percentage points = 190 total = 220 print('Correct answers: {:.2%}'.format(points/total)) Correct answers: 86.36% Data Tables width=8 print(' decimal hex binary') print('-'*27) for num in range(1,16): for base in 'dXb': print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ') print() Getting Input from the Command Line Python runs synchronously, all programs and processes will stop when listening for a user input. The input function shows a prompt to a user and waits for them to type 'ENTER'. Scripts vs Programs Programming Script : A set of code that runs in a linear fashion. The largest difference between scripts and programs is the level of complexity and purpose. Programs typically have many UI's. Python can be used to display html, css, and JS. It is common to use Python as an API (Application Programming Interface) Structured Data Sequence : The most basic data structure in Python where the index determines the order. List Tuple Range Collections : Unordered data structures, hashable values. Dictionaries Sets Iterable : Generic name for a sequence or collection; any object that can be iterated through. Can be mutable or immutable. Built In Data Types Lists are the python equivalent of arrays. empty_list = [] departments = ['HR','Development','Sales','Finance','IT','Customer Support'] You can instantiate specials = list() Test if a value is in a list. print(1 in [1, 2, 3]) #> True print(4 in [1, 2, 3]) #> False # Tuples : Very similar to lists, but they are immutable Instantiated with parentheses time_blocks = ('AM','PM') Sometimes instantiated without colors = 'red','blue','green' numbers = 1, 2, 3 Tuple() built in can be used to convert other data into a tuple tuple('abc') # returns ('a', 'b', 'c') tuple([1,2,3]) # returns (1, 2, 3) # Think of tuples as constant variables. Ranges : A list of numbers which can't be changed; often used with for loops. Declared using one to three parameters. Start : opt. default 0, first # in sequence. Stop : required next number past the last number in the sequence. Step : opt. default 1, difference between each number in the sequence. range(5) # [0, 1, 2, 3, 4] range(1,5) # [1, 2, 3, 4] range(0, 25, 5) # [0, 5, 10, 15, 20] range(0) # [ ] for let (i = 0; i < 5; i++) for let (i = 1; i < 5; i++) for let (i = 0; i < 25; i+=5) for let(i = 0; i = 0; i++) # Keep in mind that stop is not included in the range. Dictionaries : Mappable collection where a hashable value is used as a key to ref. an object stored in the dictionary. Mutable. a = {'one':1, 'two':2, 'three':3} b = dict(one=1, two=2, three=3) c = dict([('two', 2), ('one', 1), ('three', 3)]) # a, b, and c are all equal Declared with curly braces of the built in dict() Benefit of dictionaries in Python is that it doesn't matter how it is defined, if the keys and values are the same the dictionaries are considered equal. Use the in operator to see if a key exists in a dictionary. S ets : Unordered collection of distinct objects; objects that need to be hashable. Always be unique, duplicate items are auto dropped from the set. Common Uses: Removing Duplicates Membership Testing Mathematical Operators: Intersection, Union, Difference, Symmetric Difference. Standard Set is mutable, Python has a immutable version called frozenset. Sets created by putting comma seperated values inside braces: school_bag = {'book','paper','pencil','pencil','book','book','book','eraser'} print(school_bag) Also can use set constructor to automatically put it into a set. letters = set('abracadabra') print(letters) #Built-In Functions #Functions using iterables filter(function, iterable) : creates new iterable of the same type which includes each item for which the function returns true. map(function, iterable) : creates new iterable of the same type which includes the result of calling the function on every item of the iterable. sorted(iterable, key=None, reverse=False) : creates a new sorted list from the items in the iterable. Output is always a list key: opt function which coverts and item to a value to be compared. reverse: optional boolean. enumerate(iterable, start=0) : starts with a sequence and converts it to a series of tuples quarters = ['First', 'Second', 'Third', 'Fourth'] print(enumerate(quarters)) print(enumerate(quarters, start=1)) (0, 'First'), (1, 'Second'), (2, 'Third'), (3, 'Fourth')(1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth') zip(*iterables) : creates a zip object filled with tuples that combine 1 to 1 the items in each provided iterable. Functions that analyze iterable len(iterable) : returns the count of the number of items. max(*args, key=None) : returns the largest of two or more arguments. max(iterable, key=None) : returns the largest item in the iterable. key optional function which converts an item to a value to be compared. min works the same way as max sum(iterable) : used with a list of numbers to generate the total. There is a faster way to concatenate an array of strings into one string, so do not use sum for that. any(iterable) : returns True if any items in the iterable are true. all(iterable) : returns True is all items in the iterable are true. Working with dictionaries dir(dictionary) : returns the list of keys in the dictionary. Working with sets Union : The pipe | operator or union(*sets) function can be used to produce a new set which is a combination of all elements in the provided set. a = {1, 2, 3} b = {2, 4, 6} print(a | b) # => {1, 2, 3, 4, 6} Intersection : The & operator ca be used to produce a new set of only the elements that appear in all sets. a = {1, 2, 3} b = {2, 4, 6} print(a & b) # => {2} Difference : The — operator can be used to produce a new set of only the elements that appear in the first set and NOT the others. Symmetric Difference : The ^ operator can be used to produce a new set of only the elements that appear in exactly one set and not in both. a = {1, 2, 3} b = {2, 4, 6} print(a — b) # => {1, 3} print(b — a) # => {4, 6} print(a ^ b) # => {1, 3, 4, 6} For Statements In python, there is only one for loop. Always Includes: The for keyword A variable name The 'in' keyword An iterable of some kid A colon On the next line, an indented block of code called the for clause. You can use break and continue statements inside for loops as well. You can use the range function as the iterable for the for loop. print('My name is') for i in range(5): print('Carlita Cinco (' + str(i) + ')') total = 0 for num in range(101): total += num print(total) Looping over a list in Python for c in ['a', 'b', 'c']: print(c) lst = [0, 1, 2, 3] for i in lst: print(i) Common technique is to use the len() on a pre-defined list with a for loop to iterate over the indices of the list. supplies = ['pens', 'staplers', 'flame-throwers', 'binders'] for i in range(len(supplies)): print('Index ' + str(i) + ' in supplies is: ' + supplies[i]) You can loop and destructure at the same time. l = 1, 2], [3, 4], [5, 6 for a, b in l: print(a, ', ', b) Prints 1, 2 Prints 3, 4 Prints 5, 6 You can use values() and keys() to loop over dictionaries. spam = {'color': 'red', 'age': 42} for v in spam.values(): print(v) Prints red Prints 42 for k in spam.keys(): print(k) Prints color Prints age For loops can also iterate over both keys and values. Getting tuples for i in spam.items(): print(i) Prints ('color', 'red') Prints ('age', 42) Destructuring to values for k, v in spam.items(): print('Key: ' + k + ' Value: ' + str(v)) Prints Key: age Value: 42 Prints Key: color Value: red Looping over string for c in “abcdefg”: print(c) When you order arguments within a function or function call, the args need to occur in a particular order: formal positional args.*args keyword args with default values**kwargs def example(arg_1, arg_2, *args, **kwargs): pass def example2(arg_1, arg_2, *args, kw_1=”shark”, kw_2=”blowfish”, **kwargs): pass Importing in Python Modules are similar to packages in Node.js Come in different types: Built-In, Third-Party, Custom. All loaded using import statements. Terms module : Python code in a separate file. package : Path to a directory that contains modules. init.py : Default file for a package. submodule : Another file in a module's folder. function : Function in a module. A module can be any file but it is usually created by placing a special file init.py into a folder. pic Try to avoid importing with wildcards in Python. Use multiple lines for clarity when importing. from urllib.request import ( HTTPDefaultErrorHandler as ErrorHandler, HTTPRedirectHandler as RedirectHandler, Request, pathname2url, url2pathname, urlopen, ) Watching Out for Python 2 Python 3 removed <> and only uses != format() was introduced with P3 All strings in P3 are unicode and encoded. md5 was removed. ConfigParser was renamed to configparser sets were killed in favor of set() class. print was a statement in P2, but is a function in P3. Topics revisited (in python syntax) Cheat Sheet: If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: a/A-Student-Resources Edit description goofy-euclid-1cd736.netlify.app Python Cheat Sheet: If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz's gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com lorem-ipsum lorem-ipsum lorem-ipsum google-sheets-api lorem-ipsum Practice Python General Notes Python Cheat Sheet Python Snippets lorem-ipsum Python at length
    https://bgoonz-blog.netlify.app/images/code.png
  • Projects Articles
    Projects Links: Search Awesome Lists Useful Resource Archive #3 Project Image Portfolio Web Audio DAW React & Shopify Ecommerce Site (Norwex) Bgoonz Bookmarks Portfolio Goal Tracker Potluck Planner Meditation App Fancy Portfolio Mini Projects List Of Projects My Sites Embeded Websites & Projects
    https://bgoonz-blog.netlify.app/images/beige-maple.png
  • Web-Dev-Hub
    Close Menu Privacy Policy PRIVACY NOTICE Visit our website at https://bgoonz-blog.netlify.app/ Use our Facebook application — https://bgoonz-blog.netlify.app/ Engage with us in other related ways ― including any sales, marketing, or events" Website," we are referring to any website of ours that references or links to this policy" App," we are referring to any application of ours that references or links to this policy, including any listed above" Services," we are referring to our Website, App, and other related services, including any sales, marketing, or events To facilitate account creation and logon process. If you choose to link your account with us to a third-party account (such as your Google or Facebook account), we use the information you allowed us to collect from those third parties to facilitate account creation and logon process for the performance of the contract. To post testimonials. We post testimonials on our Services that may contain personal information. Prior to posting a testimonial, we will obtain your consent to use your name and the content of the testimonial. If you wish to update, or delete your testimonial, please contact us at __________ and be sure to include your name, testimonial location, and contact information.**Request feedback. **We may use your information to request feedback and to contact you about your use of our Services. To enable user-to-user communications. We may use your information in order to enable user-to-user communications with each user's consent.**To manage user accounts. **We may use your information for the purposes of managing our account and keeping it in working order.**To send administrative information to you. **We may use your personal information to send you product, service and new feature information and/or information about changes to our terms, conditions, and policies.**To protect our Services. **We may use your information as part of our efforts to keep our Services safe and secure (for example, for fraud monitoring and prevention). To enforce our terms, conditions and policies for business purposes, to comply with legal and regulatory requirements or in connection with our contract.**To respond to legal requests and prevent harm. **If we receive a subpoena or other legal request, we may need to inspect the data we hold to determine how to respond.**Fulfill and manage your orders. **We may use your information to fulfill and manage your orders, payments, returns, and exchanges made through the Services. Administer prize draws and competitions. We may use your information to administer prize draws and competitions when you elect to participate in our competitions. To deliver and facilitate delivery of services to the user. We may use your information to provide you with the requested service. To respond to user inquiries/offer support to users. We may use your information to respond to your inquiries and solve any potential issues you might have with the use of our Services. To send you marketing and promotional communications. We and/or our third-party marketing partners may use the personal information you send to us for our marketing purposes, if this is in accordance with your marketing preferences. For example, when expressing an interest in obtaining information about us or our Services, subscribing to marketing or otherwise contacting us, we will collect personal information from you. You can opt-out of our marketing emails at any time (see the " WHAT ARE YOUR PRIVACY RIGHTS?" below). Deliver targeted advertising to you. We may use your information to develop and display personalized content and advertising (and work with third parties who do so) tailored to your interests and/or location and to measure its effectiveness. Consent: We may process your data if you have given us specific consent to use your personal information for a specific purpose. Legitimate Interests: We may process your data when it is reasonably necessary to achieve our legitimate business interests. Performance of a Contract: Where we have entered into a contract with you, we may process your personal information to fulfill the terms of our contract. Legal Obligations: We may disclose your information where we are legally required to do so in order to comply with applicable law, governmental requests, a judicial proceeding, court order, or legal process, such as in response to a court order or a subpoena (including in response to public authorities to meet national security or law enforcement requirements). Vital Interests: We may disclose your information where we believe it is necessary to investigate, prevent, or take action regarding potential violations of our policies, suspected fraud, situations involving potential threats to the safety of any person and illegal activities, or as evidence in litigation in which we are involved. Business Transfers. We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company. Receiving help through our customer support channels; Participation in customer surveys or contests; and Facilitation in the delivery of our Services and to respond to your inquiries. whether we collect and use your personal information; the categories of personal information that we collect; the purposes for which the collected personal information is used; whether we sell your personal information to third parties; the categories of personal information that we sold or disclosed for a business purpose; the categories of third parties to whom the personal information was sold or disclosed for a business purpose; and the business or commercial purpose for collecting or selling personal information. you may object to the processing of your personal data you may request correction of your personal data if it is incorrect or no longer relevant, or ask to restrict the processing of the data you can designate an authorized agent to make a request under the CCPA on your behalf. We may deny a request from an authorized agent that does not submit proof that they have been validly authorized to act on your behalf in accordance with the CCPA. you may request to opt-out from future selling of your personal information to third parties. Upon receiving a request to opt-out, we will act upon the request as soon as feasibly possible, but no later than 15 days from the date of the request submission. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Leetcode Leetcode
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Javascript Cheatsheet:// Single-line comments start with two slashes. /* Multiline comments start with slash-star, and end with star-slash */ // Statements can be terminated by ; doStuff(); // ... but they don't have to be, as semicolons are automatically inserted // wherever there's a newline, except in certain cases. doStuff() // Because those cases can cause unexpected results, we'll keep on using // semicolons in this guide. /////////////////////////////////// // 1. Numbers, Strings and Operators // JavaScript has one number type (which is a 64-bit IEEE 754 double). // Doubles have a 52-bit mantissa, which is enough to store integers // up to about 9✕10¹⁵ precisely. 3; // = 3 1.5; // = 1.5 // Some basic arithmetic works as you'd expect. 1 + 1; // = 2 0.1 + 0.2; // = 0.30000000000000004 8 - 1; // = 7 10 * 2; // = 20 35 / 5; // = 7 // Including uneven division. 5 / 2; // = 2.5 // And modulo division. 10 % 2; // = 0 30 % 4; // = 2 18.5 % 7; // = 4.5 // Bitwise operations also work; when you perform a bitwise operation your float // is converted to a signed int *up to* 32 bits. 1 << 2; // = 4 // Precedence is enforced with parentheses. (1 + 3) * 2; // = 8 // There are three special not-a-real-number values: Infinity; // result of e.g. 1/0 -Infinity; // result of e.g. -1/0 NaN; // result of e.g. 0/0, stands for 'Not a Number' // There's also a boolean type. true; false; // Strings are created with ' or ". 'abc'; "Hello, world"; // Negation uses the ! symbol !true; // = false !false; // = true // Equality is === 1 === 1; // = true 2 === 1; // = false // Inequality is !== 1 !== 1; // = false 2 !== 1; // = true // More comparisons 1 < 10; // = true 1 > 10; // = false 2 <= 2; // = true 2 >= 2; // = true // Strings are concatenated with + "Hello " + "world!"; // = "Hello world!" // ... which works with more than just strings "1, 2, " + 3; // = "1, 2, 3" "Hello " + ["world", "!"]; // = "Hello world,!" // and are compared with < and > "a" < "b"; // = true // Type coercion is performed for comparisons with double equals... "5" == 5; // = true null == undefined; // = true // ...unless you use === "5" === 5; // = false null === undefined; // = false // ...which can result in some weird behaviour... 13 + !0; // 14 "13" + !0; // '13true' // You can access characters in a string with `charAt` "This is a string".charAt(0); // = 'T' // ...or use `substring` to get larger pieces. "Hello world".substring(0, 5); // = "Hello" // `length` is a property, so don't use (). "Hello".length; // = 5 // There's also `null` and `undefined`. null; // used to indicate a deliberate non-value undefined; // used to indicate a value is not currently present (although // `undefined` is actually a value itself) // false, null, undefined, NaN, 0 and "" are falsy; everything else is truthy. // Note that 0 is falsy and "0" is truthy, even though 0 == "0". /////////////////////////////////// // 2. Variables, Arrays and Objects // Variables are declared with the `var` keyword. JavaScript is dynamically // typed, so you don't need to specify type. Assignment uses a single `=` // character. var someVar = 5; // If you leave the var keyword off, you won't get an error... someOtherVar = 10; // ...but your variable will be created in the global scope, not in the scope // you defined it in. // Variables declared without being assigned to are set to undefined. var someThirdVar; // = undefined // If you want to declare a couple of variables, then you could use a comma // separator var someFourthVar = 2, someFifthVar = 4; // There's shorthand for performing math operations on variables: someVar += 5; // equivalent to someVar = someVar + 5; someVar is 10 now someVar *= 10; // now someVar is 100 // and an even-shorter-hand for adding or subtracting 1 someVar++; // now someVar is 101 someVar--; // back to 100 // Arrays are ordered lists of values, of any type. var myArray = ["Hello", 45, true]; // Their members can be accessed using the square-brackets subscript syntax. // Array indices start at zero. myArray[1]; // = 45 // Arrays are mutable and of variable length. myArray.push("World"); myArray.length; // = 4 // Add/Modify at specific index myArray[3] = "Hello"; // Add and remove element from front or back end of an array myArray.unshift(3); // Add as the first element someVar = myArray.shift(); // Remove first element and return it myArray.push(3); // Add as the last element someVar = myArray.pop(); // Remove last element and return it // Join all elements of an array with semicolon var myArray0 = [32,false,"js",12,56,90]; myArray0.join(";") // = "32;false;js;12;56;90" // Get subarray of elements from index 1 (include) to 4 (exclude) myArray0.slice(1,4); // = [false,"js",12] // Remove 4 elements starting from index 2, and insert there strings // "hi","wr" and "ld"; return removed subarray myArray0.splice(2,4,"hi","wr","ld"); // = ["js",12,56,90] // myArray0 === [32,false,"hi","wr","ld"] // JavaScript's objects are equivalent to "dictionaries" or "maps" in other // languages: an unordered collection of key-value pairs. var myObj = {key1: "Hello", key2: "World"}; // Keys are strings, but quotes aren't required if they're a valid // JavaScript identifier. Values can be any type. var myObj = {myKey: "myValue", "my other key": 4}; // Object attributes can also be accessed using the subscript syntax, myObj["my other key"]; // = 4 // ... or using the dot syntax, provided the key is a valid identifier. myObj.myKey; // = "myValue" // Objects are mutable; values can be changed and new keys added. myObj.myThirdKey = true; // If you try to access a value that's not yet set, you'll get undefined. myObj.myFourthKey; // = undefined /////////////////////////////////// // 3. Logic and Control Structures // The `if` structure works as you'd expect. var count = 1; if (count == 3){ // evaluated if count is 3 } else if (count == 4){ // evaluated if count is 4 } else { // evaluated if it's not either 3 or 4 } // As does `while`. while (true){ // An infinite loop! } // Do-while loops are like while loops, except they always run at least once. var input; do { input = getInput(); } while (!isValid(input)); // The `for` loop is the same as C and Java: // initialization; continue condition; iteration. for (var i = 0; i < 5; i++){ // will run 5 times } // Breaking out of labeled loops is similar to Java outer: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (i == 5 && j ==5) { break outer; // breaks out of outer loop instead of only the inner one } } } // The for/in statement allows iteration over properties of an object. var description = ""; var person = {fname:"Paul", lname:"Ken", age:18}; for (var x in person){ description += person[x] + " "; } // description = 'Paul Ken 18 ' // The for/of statement allows iteration over iterable objects (including the built-in String, // Array, e.g. the Array-like arguments or NodeList objects, TypedArray, Map and Set, // and user-defined iterables). var myPets = ""; var pets = ["cat", "dog", "hamster", "hedgehog"]; for (var pet of pets){ myPets += pet + " "; } // myPets = 'cat dog hamster hedgehog ' // && is logical and, || is logical or if (house.size == "big" && house.colour == "blue"){ house.contains = "bear"; } if (colour == "red" || colour == "blue"){ // colour is either red or blue } // && and || "short circuit", which is useful for setting default values. var name = otherName || "default"; // The `switch` statement checks for equality with `===`. // Use 'break' after each case // or the cases after the correct one will be executed too. grade = 'B'; switch (grade) { case 'A': console.log("Great job"); break; case 'B': console.log("OK job"); break; case 'C': console.log("You can do better"); break; default: console.log("Oy vey"); break; } /////////////////////////////////// // 4. Functions, Scope and Closures // JavaScript functions are declared with the `function` keyword. function myFunction(thing){ return thing.toUpperCase(); } myFunction("foo"); // = "FOO" // Note that the value to be returned must start on the same line as the // `return` keyword, otherwise you'll always return `undefined` due to // automatic semicolon insertion. Watch out for this when using Allman style. function myFunction(){ return // <- semicolon automatically inserted here {thisIsAn: 'object literal'}; } myFunction(); // = undefined // JavaScript functions are first class objects, so they can be reassigned to // different variable names and passed to other functions as arguments - for // example, when supplying an event handler: function myFunction(){ // this code will be called in 5 seconds' time } setTimeout(myFunction, 5000); // Note: setTimeout isn't part of the JS language, but is provided by browsers // and Node.js. // Another function provided by browsers is setInterval function myFunction(){ // this code will be called every 5 seconds } setInterval(myFunction, 5000); // Function objects don't even have to be declared with a name - you can write // an anonymous function definition directly into the arguments of another. setTimeout(function(){ // this code will be called in 5 seconds' time }, 5000); // JavaScript has function scope; functions get their own scope but other blocks // do not. if (true){ var i = 5; } i; // = 5 - not undefined as you'd expect in a block-scoped language // This has led to a common pattern of "immediately-executing anonymous // functions", which prevent temporary variables from leaking into the global // scope. (function(){ var temporary = 5; // We can access the global scope by assigning to the "global object", which // in a web browser is always `window`. The global object may have a // different name in non-browser environments such as Node.js. window.permanent = 10; })(); temporary; // raises ReferenceError permanent; // = 10 // One of JavaScript's most powerful features is closures. If a function is // defined inside another function, the inner function has access to all the // outer function's variables, even after the outer function exits. function sayHelloInFiveSeconds(name){ var prompt = "Hello, " + name + "!"; // Inner functions are put in the local scope by default, as if they were // declared with `var`. function inner(){ alert(prompt); } setTimeout(inner, 5000); // setTimeout is asynchronous, so the sayHelloInFiveSeconds function will // exit immediately, and setTimeout will call inner afterwards. However, // because inner is "closed over" sayHelloInFiveSeconds, inner still has // access to the `prompt` variable when it is finally called. } sayHelloInFiveSeconds("Adam"); // will open a popup with "Hello, Adam!" in 5s /////////////////////////////////// // 5. More about Objects; Constructors and Prototypes // Objects can contain functions. var myObj = { myFunc: function(){ return "Hello world!"; } }; myObj.myFunc(); // = "Hello world!" // When functions attached to an object are called, they can access the object // they're attached to using the `this` keyword. myObj = { myString: "Hello world!", myFunc: function(){ return this.myString; } }; myObj.myFunc(); // = "Hello world!" // What this is set to has to do with how the function is called, not where // it's defined. So, our function doesn't work if it isn't called in the // context of the object. var myFunc = myObj.myFunc; myFunc(); // = undefined // Inversely, a function can be assigned to the object and gain access to it // through `this`, even if it wasn't attached when it was defined. var myOtherFunc = function(){ return this.myString.toUpperCase(); }; myObj.myOtherFunc = myOtherFunc; myObj.myOtherFunc(); // = "HELLO WORLD!" // We can also specify a context for a function to execute in when we invoke it // using `call` or `apply`. var anotherFunc = function(s){ return this.myString + s; }; anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!" // The `apply` function is nearly identical, but takes an array for an argument // list. anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!" // This is useful when working with a function that accepts a sequence of // arguments and you want to pass an array. Math.min(42, 6, 27); // = 6 Math.min([42, 6, 27]); // = NaN (uh-oh!) Math.min.apply(Math, [42, 6, 27]); // = 6 // But, `call` and `apply` are only temporary. When we want it to stick, we can // use `bind`. var boundFunc = anotherFunc.bind(myObj); boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!" // `bind` can also be used to partially apply (curry) a function. var product = function(a, b){ return a * b; }; var doubler = product.bind(this, 2); doubler(8); // = 16 // When you call a function with the `new` keyword, a new object is created, and // made available to the function via the `this` keyword. Functions designed to be // called like that are called constructors. var MyConstructor = function(){ this.myNumber = 5; }; myNewObj = new MyConstructor(); // = {myNumber: 5} myNewObj.myNumber; // = 5 // Unlike most other popular object-oriented languages, JavaScript has no // concept of 'instances' created from 'class' blueprints; instead, JavaScript // combines instantiation and inheritance into a single concept: a 'prototype'. // Every JavaScript object has a 'prototype'. When you go to access a property // on an object that doesn't exist on the actual object, the interpreter will // look at its prototype. // Some JS implementations let you access an object's prototype on the magic // property `__proto__`. While this is useful for explaining prototypes it's not // part of the standard; we'll get to standard ways of using prototypes later. var myObj = { myString: "Hello world!" }; var myPrototype = { meaningOfLife: 42, myFunc: function(){ return this.myString.toLowerCase(); } }; myObj.__proto__ = myPrototype; myObj.meaningOfLife; // = 42 // This works for functions, too. myObj.myFunc(); // = "hello world!" // Of course, if your property isn't on your prototype, the prototype's // prototype is searched, and so on. myPrototype.__proto__ = { myBoolean: true }; myObj.myBoolean; // = true // There's no copying involved here; each object stores a reference to its // prototype. This means we can alter the prototype and our changes will be // reflected everywhere. myPrototype.meaningOfLife = 43; myObj.meaningOfLife; // = 43 // The for/in statement allows iteration over properties of an object, // walking up the prototype chain until it sees a null prototype. for (var x in myObj){ console.log(myObj[x]); } ///prints: // Hello world! // 43 // [Function: myFunc] // true // To only consider properties attached to the object itself // and not its prototypes, use the `hasOwnProperty()` check. for (var x in myObj){ if (myObj.hasOwnProperty(x)){ console.log(myObj[x]); } } ///prints: // Hello world! // We mentioned that `__proto__` was non-standard, and there's no standard way to // change the prototype of an existing object. However, there are two ways to // create a new object with a given prototype. // The first is Object.create, which is a recent addition to JS, and therefore // not available in all implementations yet. var myObj = Object.create(myPrototype); myObj.meaningOfLife; // = 43 // The second way, which works anywhere, has to do with constructors. // Constructors have a property called prototype. This is *not* the prototype of // the constructor function itself; instead, it's the prototype that new objects // are given when they're created with that constructor and the new keyword. MyConstructor.prototype = { myNumber: 5, getMyNumber: function(){ return this.myNumber; } }; var myNewObj2 = new MyConstructor(); myNewObj2.getMyNumber(); // = 5 myNewObj2.myNumber = 6; myNewObj2.getMyNumber(); // = 6 // Built-in types like strings and numbers also have constructors that create // equivalent wrapper objects. var myNumber = 12; var myNumberObj = new Number(12); myNumber == myNumberObj; // = true // Except, they aren't exactly equivalent. typeof myNumber; // = 'number' typeof myNumberObj; // = 'object' myNumber === myNumberObj; // = false if (0){ // This code won't execute, because 0 is falsy. } if (new Number(0)){ // This code will execute, because wrapped numbers are objects, and objects // are always truthy. } // However, the wrapper objects and the regular builtins share a prototype, so // you can actually add functionality to a string, for instance. String.prototype.firstCharacter = function(){ return this.charAt(0); }; "abc".firstCharacter(); // = "a" // This fact is often used in "polyfilling", which is implementing newer // features of JavaScript in an older subset of JavaScript, so that they can be // used in older environments such as outdated browsers. // For instance, we mentioned that Object.create isn't yet available in all // implementations, but we can still use it with this polyfill: if (Object.create === undefined){ // don't overwrite it if it exists Object.create = function(proto){ // make a temporary constructor with the right prototype var Constructor = function(){}; Constructor.prototype = proto; // then use it to create a new, appropriately-prototyped object return new Constructor(); }; } /* ******************************************************************************************* * GLOBAL OBJECTS > OBJECT * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object * ******************************************************************************************* */ // Global object: properties Object.length // length is a property of a function object, and indicates how many arguments the function expects, i.e. the number of formal parameters. This number does not include the rest parameter. Has a value of 1. Object.prototype // Represents the Object prototype object and allows to add new properties and methods to all objects of type Object. // Methods of the Object constructor Object.assign(target, ...sources) // Copies the values of all enumerable own properties from one or more source objects to a target object. method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object Object.create(MyObject) // Creates a new object with the specified prototype object and properties. The object which should be the prototype of the newly-created object. Object.defineProperty(obj, prop, descriptor) // Adds the named property described by a given descriptor to an object. Object.defineProperties(obj, props) // Adds the named properties described by the given descriptors to an object. Object.entries(obj) // Returns an array containing all of the [key, value] pairs of a given object's own enumerable string properties. Object.freeze(obj) // Freezes an object: other code can't delete or change any properties. Object.getOwnPropertyDescriptor(obj, prop) // Returns a property descriptor for a named property on an object. Object.getOwnPropertyDescriptors(obj) // Returns an object containing all own property descriptors for an object. Object.getOwnPropertyNames(obj) // Returns an array containing the names of all of the given object's own enumerable and non-enumerable properties. Object.getOwnPropertySymbols(obj) // Returns an array of all symbol properties found directly upon a given object. Object.getPrototypeOf(obj) // Returns the prototype of the specified object. Object.is(value1, value2); // Compares if two values are the same value. Equates all NaN values (which differs from both Abstract Equality Comparison and Strict Equality Comparison). Object.isExtensible(obj) // Determines if extending of an object is allowed. Object.isFrozen(obj) // Determines if an object was frozen. Object.isSealed(obj) // Determines if an object is sealed. Object.keys(obj) // Returns an array containing the names of all of the given object's own enumerable string properties. Object.preventExtensions(obj) // Prevents any extensions of an object. Object.seal(obj) // Prevents other code from deleting properties of an object. Object.setPrototypeOf(obj, prototype) // Sets the prototype (i.e., the internal [[Prototype]] property). Object.values(obj) // Returns an array containing the values that correspond to all of a given object's own enumerable string properties. // Object instances and Object prototype object (Object.prototype.property or Object.prototype.method()) // Properties obj.constructor // Specifies the function that creates an object's prototype. obj.__proto__ // Points to the object which was used as prototype when the object was instantiated. // Methods obj.hasOwnProperty(prop) // Returns a boolean indicating whether an object contains the specified property as a direct property of that object and not inherited through the prototype chain. prototypeObj.isPrototypeOf(object) // Returns a boolean indicating whether the object this method is called upon is in the prototype chain of the specified object. obj.propertyIsEnumerable(prop) // Returns a boolean indicating if the internal ECMAScript [[Enumerable]] attribute is set. obj.toLocaleString() // Calls toString(). obj.toString() // Returns a string representation of the object. object.valueOf() // Returns the primitive value of the specified object. /* ******************************************************************************************* * GLOBAL OBJECTS > ARRAY * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array * ******************************************************************************************* */ // Global object: properties Array.length // Reflects the number of elements in an array. Array.prototype // Represents the prototype for the Array constructor and allows to add new properties and methods to all Array objects. // Global object: methods Array.from(arrayLike[, mapFn[, thisArg]]) // Creates a new Array instance from an array-like or iterable object. Array.isArray(obj) // Returns true if a variable is an array, if not false. Array.of(element0[, element1[, ...[, elementN]]]) // Creates a new Array instance with a variable number of arguments, regardless of number or type of the arguments. // Instance: properties arr.length // Reflects the number of elements in an array. // Instance: mutator methods arr.copyWithin(target, start, end) // Copies a sequence of array elements within the array. arr.fill(value, start, end) // Fills all the elements of an array from a start index to an end index with a static value. arr.pop() // Removes the last element from an array and returns that element. arr.push([element1[, ...[, elementN]]]) // Adds one or more elements to the end of an array and returns the new length of the array. arr.reverse() // Reverses the order of the elements of an array in place — the first becomes the last, and the last becomes the first. arr.shift() // Removes the first element from an array and returns that element. arr.sort() // Sorts the elements of an array in place and returns the array. array.splice(start, deleteCount, item1, item2, ...) // Adds and/or removes elements from an array. arr.unshift([element1[, ...[, elementN]]]) // Adds one or more elements to the front of an array and returns the new length of the array. // Instance: accessor methods arr.concat(value1[, value2[, ...[, valueN]]]) // Returns a new array comprised of this array joined with other array(s) and/or value(s). arr.includes(searchElement, fromIndex) // Determines whether an array contains a certain element, returning true or false as appropriate. arr.indexOf(searchElement[, fromIndex]) // Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found. arr.join(separator) // Joins all elements of an array into a string. arr.lastIndexOf(searchElement, fromIndex) // Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found. arr.slice(begin, end) // Extracts a section of an array and returns a new array. arr.toString() // Returns a string representing the array and its elements. Overrides the Object.prototype.toString() method. arr.toLocaleString(locales, options) // Returns a localized string representing the array and its elements. Overrides the Object.prototype.toLocaleString() method. // Instance: iteration methods arr.entries() // Returns a new Array Iterator object that contains the key/value pairs for each index in the array. arr.every(callback[, thisArg]) // Returns true if every element in this array satisfies the provided testing function. arr.filter(callback[, thisArg]) // Creates a new array with all of the elements of this array for which the provided filtering function returns true. arr.find(callback[, thisArg]) // Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found. arr.findIndex(callback[, thisArg]) // Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found. arr.forEach(callback[, thisArg]) // Calls a function for each element in the array. arr.keys() // Returns a new Array Iterator that contains the keys for each index in the array. arr.map(callback[, initialValue]) // Creates a new array with the results of calling a provided function on every element in this array. arr.reduce(callback[, initialValue]) // Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value. arr.reduceRight(callback[, initialValue]) // Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value. arr.some(callback[, initialValue]) // Returns true if at least one element in this array satisfies the provided testing function. arr.values() // Returns a new Array Iterator object that contains the values for each index in the array. Fundamental Javascript Concepts You Should Understand Plain Old JS Object Lesson Concepts Fundamental Javascript Concepts You Should Understand Plain Old JS Object Lesson Concepts- Label variables as either Primitive vs. Reference - primitives: strings, booleans, numbers, null and undefined - primitives are immutable - refereces: objects (including arrays) - references are mutable - Identify when to use `.` vs `[]` when accessing values of an object - dot syntax `object.key` - easier to read - easier to write - cannot use variables as keys - keys cannot begin with a number - bracket notation `object["key]` - allows variables as keys - strings that start with numbers can be use as keys - Write an object literal with a variable key using interpolation put it in brackets to access the value of the variable, rather than just make the value that string let a = "b"; let obj = { a: "letter_a", [a]: "letter b" } Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object can also use (key in object) syntax interchangeably (returns a boolean) Utilize Object.keys and Object.values in a function Object.keys(obj) returns an array of all the keys in obj Object.values(obj) returns an array of the values in obj Iterate through an object using a for in loop let printValues = function(obj) { for (let key in obj) { let value = obj[key]; console.log(value); } } Define a function that utilizes ...rest syntax to accept an arbitrary number of arguments...rest syntax will store all additional arguments in an array array will be empty if there are no additional arguments let myFunction = function(str, ...strs) { console.log("The first string is " + str); console.log("The rest of the strings are:"); strs.forEach(function(str) { console.log(str); }) } Use ...spread syntax for Object literals and Array literals let arr1 = ["a", "b", "c"]; let longer = [...arr1, "d", "e"]; // ["a", "b", "c", "d", "e"] // without spread syntax, this would give you a nested array let withoutRest = [arr1, "d", "e"] // [["a", "b", "c"], "d", "e"] Destructure an array to reference specific elements let array = [35, 9]; let [firstEl, secondEl] = array; console.log(firstEl); // => 35 console.log(secondEl); // => 9 // can also destructure using … syntax let array = [35, 9, 14]; let [head, …tail] = array; console.log(head); // => 35 console.log(tail); // => [9, 14] -Destructure an object to reference specific values - if you want to use variable names that don 't match the keys, you can use aliasing - `let { oldkeyname: newkeyname } = object` - rule of thumb— only destructure values from objects that are two levels deep `` `javascript let obj = { name: "Wilfred", appearance: ["short", "mustache"], favorites: { color: "mauve", food: "spaghetti squash", number: 3 } } // with variable names that match keys let { name, appearance } = obj; console.log(name); // "Wilfred" console.log(appearance); // ["short", "mustache"] // with new variable names (aliasing) let {name: myName, appearance: myAppearance} = obj; console.log(myName); // "Wilfred" console.log(myAppearance); // ["short", "mustache"] // in a function call let sayHello = function({name}) { console.log("Hello, " + name); // "Hello Wilfred" } // nested objects + aliasing let { favorites: {color, food: vegetable} } = obj; console.log(color, vegetable); //=> mauve spaghetti squash Write a function that accepts a array as an argument and returns an object representing the count of each character in the array// let elementCounts = function(array) { let obj = {}; array.forEach(function(el) { if (el in obj) obj[el] += 1; else obj[el] = 1; }) return obj; } console.log(elementCounts(["e", "f", "g", "f"])); // => Object {e: 1, f: 2, g: 1} Callbacks Lesson Concepts Given multiple plausible reasons, identify why functions are called “First Class Objects” in JavaScript. they can be stored in variables, passed as arguments to other functions, and serve as return value for a function supports same basic operations as other types (strings, bools, numbers) higher-order functions take functions as arguments or return functions as values Given a code snippet containing an anonymous callback, a named callback, and multiple console.log s, predict what will be printed what is this referring to? Write a function that takes in a value and two callbacks. The function should return the result of the callback that is greater. let greaterCB = function(val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); } let greaterCB = function(val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); } // shorter version let greaterCB = function(val, callback1, callback2) { return Math.max(callback1(val), callback2(val)); } // even shorter, cause why not let greaterCB = (val, cb1, cb2) => Math.max(cb1(val), cb2(val));-Write a function, myMap, that takes in an array and a callback as arguments.The function should mimic the behavior of `Array#map`. `` `javascript let myMap = function(array, callback) { let newArr = []; for (let i = 0; i < array.length; i ++) { mapped = callback(array[i], i, array); newArr.push(mapped); } return newArr; } console.log( myMap([16,25,36], Math.sqrt)); // => [4, 5, 6]; let myMapArrow = (array, callback) => { let newArr = []; array.forEach( (ele, ind, array) => { newArr.push(callback(ele, ind, array)); }) return newArr; } console.log(myMapArrow([16,25,36], Math.sqrt)); // => [4, 5, 6]; Write a function, myFilter, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#filter. let myFilter = function(array, callback) { let filtered = []; for (let i = 0; i < array.length; i++) { if (callback(array[i])) { filtered.push(array[i], i, array); } } } Write a function, myEvery, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#every. let myEvery = function(array, callback) { for (let i = 0; i < array.length; i++) { if (!callback(array[i], i, array)) { return false } } return true; } // with arrow function syntax let myEvery = (array, callback) => { for (let i = 0; i < array.length; i++) { if (!callback(array[i])) { return false } } return true; } Scope Lesson Concepts Identify the difference between const, let, and var declarations const - cannot reassign variable, scoped to block let - can reassign variable, scoped to block var - outdated, may or may not be reassigned, scoped to function. can be not just reassigned, but also redeclared! a variable will always evaluate to the value it contains regardless of how it was declared Explain the difference between const, let, and var declarations var is function scoped—so if you declare it anywhere in a function, the declaration (but not assignment) is "hoisted" so it will exist in memory as “undefined” which is bad and unpredictable var will also allow you to redeclare a variable, while let or const will raise a syntax error. you shouldn't be able to do that! const won't let you reassign a variable, but if it points to a mutable object, you will still be able to change the value by mutating the object block-scoped variables allow new variables with the same name in new scopes block-scoped still performs hoisting of all variables within the block, but it doesn’t initialize to the value of undefined like var does, so it throws a specific reference error if you try to access the value before it has been declared if you do not use var or let or const when initializing, it will be declared as global—THIS IS BAD if you assign a value without a declaration, it exists in the global scope (so then it would be accessible by all outer scopes, so bad). however, there’s no hoisting, so it doesn’t exist in the scope until after the line is run Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining scope of a program means the set of variables that are available for use within the program global scope is represented by the window object in the browser and the global object in Node.js global variables are available everywhere, and so increase the risk of name collisions local scope is the set of variables available for use within the function when we enter a function, we enter a new scope includes functions arguments, local variables declared inside function, and any variables that were already declared when the function is defined (hmm about that last one) for blocks (denoted by curly braces {}, as in conditionals or for loops), variables can be block scoped inner scope does not have access to variables in the outer scope scope chaining — if a given variable is not found in immediate scope, javascript will search all accessible outer scopes until variable is found so an inner scope can access outer scope variables but an outer scope can never access inner scope variables Define an arrow function let arrowFunction = (param1, param2) => { let sum = param1 + param2; return sum; } // with 1 param you can remove parens around parameters let arrowFunction = param => // if your return statement is one line, you can use implied return let arrowFunction = param => param + 1; // you don’t have to assign to variable, can be anonymous // if you never need to use it again param => param + 1; Given an arrow function, deduce the value of this without executing the code arrow functions are automatically bound to the context they were declared in. unlike regular function which use the context they are invoked in (unless they have been bound using Function#bind). if you implement an arrow function as a method in an object the context it will be bound to is NOT the object itself, but the global context. so you can’t use an arrow function to define a method directly let obj = { name: “my object”, unboundFunc: function () { return this.name; // this function will be able to be called on different objects }, boundToGlobal: () => { return this.name; // this function, no matter how you call it, will be called // on the global object, and it cannot be rebound // this is because it was defined using arrow syntax }, makeFuncBoundToObj: function() { return () => { return this.name; } // this function will return a function that will be bound // to the object where we call the outer method // because the arrow syntax is nested inside one of this // function's methods, it cannot be rebound }, makeUnboundFunc: function() { return function() { return this.name; } //this function will return a function that will still be unbound }, immediatelyInvokedFunc: function() { return this.name; }(), // this property will be set to the return value of this anonymous function, // which is invoked during the object definition; // basically, it's a way to check the context inside of an object, at this moment innerObj: { name: "inner object", innerArrowFunc: () => { return this.name; } // the context inside a nested object is not the parent, it's still // the global object. entering an object definition doesn't change the context }, let otherObj = { name: "my other object" } // call unboundFunc on obj, we get "my object" console.log("unboundFunc: ", obj.unboundFunc()); // => "my object" // assign unboundFunc to a variable and call it let newFunc = obj.unboundFunc; // this newFunc will default to being called on global object console.log("newFunc: ",newFunc()); // => undefined // but you could bind it directly to a different object if you wanted console.log("newFunc: ", newFunc.bind(otherObj)()); // "my other object" // meanwhile, obj.boundToGlobal will only ever be called on global object console.log("boundToGlobal: ", obj.boundToGlobal()); //=> undefined let newBoundFunc = obj.boundToGlobal; console.log("newBoundFunc: ", newBoundFunc()); // => undefined // even if you try to directly bind to another object, it won't work! console.log("newBoundFunc: ", newBoundFunc.bind(otherObj)()); // => undefined // let's make a new function that will always be bound to the context // where we call our function maker let boundFunc = obj.makeFuncBoundToObj();// note that we're invoking, not just assigning console.log("boundFunc: ", boundFunc()); // => "my object" // we can't rebind this function console.log("boundFunc: ", boundFunc.bind(otherObj)()) // =>"my object" // but if I call makeFuncBoundToObj on another context // the new bound function is stuck with that other context let boundToOther = obj.makeFuncBoundToObj.bind(otherObj)(); console.log("boundToOther: ", boundToOther()); // => "my other object" console.log("boundToOther: ", boundToOther.bind(obj)()) // "my other object" // the return value of my immediately invoked function // shows that the context inside of the object is the // global object, not the object itself // context only changes inside a function that is called // on an object console.log("immediatelyInvokedFunc: ", obj.immediatelyInvokedFunc); // => undefined // even though we're inside a nested object, the context is // still the same as it was outside the outer object // in this case, the global object console.log("innerArrowFunc: ", obj.innerObj.innerArrowFunc()); // => undefined } -Implement a closure and explain how the closure effects scope - a closure is "the combination of a function and the lexical environment within which that function was declared" - alternatively, "when an inner function uses or changes variables in an outer function" - closures have access to any variables within their own scope + scope of outer functions + global scope— the set of all these available variables is "lexical environemnt" - closure keeps reference to all variables ** even if the outer function has returned ** -each function has a private mutable state that cannot be accessed externally - the inner function will maintain a reference to the scope in which it was declared.so it has access to variables that were initialized in any outer scope— even if that scope - if a variable exists in the scope of what could have been accessed by a function(e.g.global scope, outer function, etc), does that variable wind up in the closure even if it never got accessed ? - if you change the value of a variable(e.g.i++) you will change the value of that variable in the scope that it was declared in `` `javascript function createCounter() { // this function starts a counter at 0, then returns a // new function that can access and change that counter // // each new counter you create will have a single internal // state, that can be changed only by calling the function. // you can't access that state from outside of the function, // even though the count variable in question is initialized // by the outer function, and it remains accessible to the // inner function after the outer function returns. let count = 0; return function() { count ++; return count; } } let counter = createCounter(); console.log(counter()); //=> 1 console.log(counter()); //=> 2 // so the closure here comes into play because // an inner function is accessing and changing // a variable from an outer function // the closure is the combination of the counter // function and the all the variables that existed // in the scope that it was declared in. because // inner blocks/functions have access to outer // scopes, that includes the scope of the outer // function. // so counter variable is a closure, in that // it contains the inner count value that was // initialized by the outer createCounter() function // count has been captured or closed over // this state is private, so if i run createCounter again // i get a totally separate count that doesn't interact // with the previous one and each of the new functions // will have their own internal state based on the // initial declaration in the now-closed outer function let counter2 = createCounter(); console.log(counter2()); // => 1 // if i set a new function equal to my existing counter // the internal state is shared with the new function let counter3 = counter2; console.log(counter3()); Define a method that references this on an object literal when we use this in a method it refers to the object that the method is invoked on it will let you access other pieces of information from within that object, or even other methods method style invocation — object.method(args) (e.g. built in examples like Array#push, or String#toUpperCase) context is set every time we invoke a function function style invocation sets the context to the global object no matter what being inside an object does not make the context that object! you still have to use method-style invocation Utilize the built in Function#bind on a callback to maintain the context of this when we call bind on a function, we get an exotic function back — so the context will always be the same for that new function let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function // we can use the built in Function.bind to ensure our context, our this, // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints "meow" -`bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context.the first arg will be the context aka the `this` you want it to use.the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won 't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope(which itself has pointers to new scopes until you reach the global scope.so you can think about a whole given block 's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function -so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object 's method on something other than that object, and then this would refer to the context where/how it was called, e.g. `` `javascript let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; // note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined // our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn’t exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; global.setTimeout(cat.purrMore, 5000); // 5 seconds later: TypeError: this.purr is not a function we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function // we can use the built in Function.bind to ensure our context, our this , // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints “meow” -`bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context.the first arg will be the context aka the `this` you want it to use.the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won 't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope(which itself has pointers to new scopes until you reach the global scope.so you can think about a whole given block 's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function -so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object 's method on something other than that object, and then this would refer to the context where/how it was called, e.g. `` `javascript let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; // note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined // our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn’t exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined POJOs 1. Label variables as either Primitive vs. Reference Javascript considers most data types to be ‘primitive’, these data types are immutable, and are passed by value. The more complex data types: Array and Object are mutable, are considered ‘reference’ data types, and are passed by reference. Boolean — Primitive Null — Primitive Undefined — Primitive Number — Primitive String — Primitive Array — Reference Object — Reference Function — Reference 2. Identify when to use . vs [] when accessing values of an object let obj = { "one": 1, "two": 2 }; // Choose the square brackets property accessor when the property name is determined at // runtime, or if the property name is not a valid identifier let myKey = "one"; console.log(obj[myKey]); // Choose the dot property accessor when the property name is known ahead of time. console.log(obj.two); 3. Write an object literal with a variable key using interpolation let keyName = "two"; // If the key is not known, you can use an alternative `[]` syntax for // object initialization only let obj2 = { [keyName]: 2 } console.log(obj2); 4. Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object function doesKeyExist(obj, key) { // obj[key] !== undefined // or: return key in obj; } let course = { bootcamp: 'Lambda', course: 'Bootcamp Prep' } console.log(doesKeyExist(course, 'course')); // => true console.log(doesKeyExist(course, 'name')); // => false 5. Utilize Object.keys and Object.values in a function function printKeys(object) { return Object.keys(object); } function printValues(object) { return Object.values(object); } console.log(printKeys({ dog: "Strelka", dog2: "Belka" })); console.log(printValues({ dog: "Strelka", dog2: "Belka" })); 6. Iterate through an object using a for in loop let player = { name: "Sergey", skill: "hockey" }; for (let key in player) { console.log(key, player[key]); } console.log(Object.entries(player)); 7. Define a function that utilizes …rest syntax to accept an arbitrary number of arguments function restSum(...otherNums) { let sum = 0; console.log(otherNums); otherNums.forEach(function(num) { sum += num; }); return sum; } console.log(restSum(3, 5, 6)); // => 14 console.log(restSum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // => 45 console.log(restSum(0)); // => 0 8. Use …spread syntax for Object literals and Array literals let numArray = [1, 2, 3]; let moreNums = [...numArray, 4, 5, 6] console.log(moreNums); let shoe = { color: "red", size: 10 }; let newShoe = { ...shoe, brand: "Nike", size: 12 }; console.log(newShoe); newShoe.color = "black"; console.log(newShoe); console.log(shoe); 9. Destructure an array to reference specific elements let arr = ['one', 'two', 'three']; let [first] = arr; console.log(first); 10. Destructure an object to reference specific values let me = { name: "Ian", instruments: ['bass', 'synth', 'guitar'], siblings: { brothers: ['Alistair'], sisters: ['Meghan'] } } let { name, instruments: musical_instruments, siblings: { sisters } } = me; console.log(name); console.log(musical_instruments); console.log(sisters); 11. Write a function that accepts a string as an argument and returns an object representing the count of each character in the array function charCount(inputString) { let res = inputString.split("").reduce(function(accum, el) { if (el in accum) { accum[el] = accum[el] + 1; } else { accum[el] = 1; } return accum; }, {}) return res; } console.log(charCount('aaabbbeebbcdkjfalksdfjlkasdfasdfiiidkkdingds')); Review of Concepts 1. Identify the difference between const, let, and var declarations 2. Explain the difference between const, let, and var declarations var a = "a"; var is the historical keyword used for variable declaration. var declares variables in function scope, or global scope if not inside a function. We consider var to be deprecated and it is never used in this course. let b = "b"; let is the keyword we use most often for variable declaration. let declares variables in block scope. variables declared with let are re-assignable. const c = "c"; const is a specialized form of let that can only be used to initialize a variable. Except when it is declared, you cannot assign to a const variable. const scopes variables the same way that let does. 3. Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining Consider this run function, inside which foo and bar have function scope . i and baz are scoped to the block expression.// function and block scope in this example function run() { var foo = "Foo"; let bar = "Bar"; console.log(foo, bar); { console.log(foo); let baz = "Bazz"; console.log(baz); } console.log(baz); // ReferenceError } run(); Notice that referencing baz from outside it's block results in JavaScript throwing a ReferenceError. Consider this run function, inside of which foo has function scope . function run() { console.log(foo); // undefined var foo = "Foo"; console.log(foo); // Foo } run(); Consider this func1 function and it's nested scopes.// global scope function func1(arg1) { // func1 scope return function func2(arg2) { // func2 scope return function func3(arg3) { // func3 scope console.log(arg1, arg2, arg3); } } } 6. Implement a closure and explain how the closure effects scope const adder = (arg1) => { return (arg2) => { return arg1 + arg2; } }; const func2 = adder(2); const result = func2(2); console.log(result); // => 4; 4. Define an arrow function const returnValue = (val) => val; This simple construct will create a function that accepts val as a parameter, and returns val immediately. We do not need to type return val , because this is a single-line function. Identically, we could write const returnValue = (val) => { return val; }; 5. Given an arrow function, deduce the value of this without executing the code function fDAdder(arr) { console.log(this); return arr.reduce((acc, ele) => { return acc + ele; }); }; fDAdder([1, 2, 4, 6]); If we use a function declaration style function, the this variable is set to the global object (i.e. Object [global] in Node. JS and Window in your browser). const adder = (arr) => { console.log(this); arr.reduce((acc, ele) => sum += ele); }; adder([1, 2, 4, 6]); In this example, we use a fat arrow style function. Note that when we declare a functions like this this becomes 7. Define a method that references this on an object literal const pokemon = { firstname: 'Pika', lastname: 'Chu', getPokeName: function() { const fullname = `${this.firstname} ${this.lastname}`; return fullname; } }; console.log(pokemon.getPokeName()); 8. Utilize the built in Function#bind on a callback to maintain the context of this const pokemon = { firstname: 'Pika', lastname: 'Chu', getPokeName: function() { const fullname = `${this.firstname} ${this.lastname}`; return fullname; } }; const logPokemon = pokemon.getPokename.bind(pokemon); logPokemon('sushi', 'algorithms'); // Pika Chu loves sushi and algorithms 9. Given a code snippet, identify what this refers to function Person(name) { // this.name = name; // let that = this; setTimeout(function() { // console.log(this); // => Window // console.log(that); // => [Function] => Person // this.sayName(); // => no method error that.sayName(); }, 1000); } Person.prototype.sayName = function() { console.log(this.name); }; const jane = new Person("Jane"); The Complete JavaScript Reference Guide The Complete JavaScript Reference Guide### How to learn effectively Learning: The acquisition of skills and the ability to apply them in the future. What makes an Effective learner? They are active listeners. They are engaged with the material. They are receptive of feedback. They are open to difficulty. Why do active learning techniques feel difficult? It feels difficult because you are constantly receiving feedback, and so you are constantly adapting and perfecting the material. Desirable Difficulty The skills we wish to obtain is often a difficult one. We want challenging but possible lessons based on current level of skill. Effective learners space their practice Consistent effort > cramming => for durable knowledge Getting visual feedback in your programs The first command we'll learn in JavaScript is console.log. This command is used to print something onto the screen. As we write our first lines of code, we'll be using console.log frequently as a way to visually see the output of our programs. Let's write our first program: console.log("hello world"); console.log("how are you?"); Executing the program above would print out the following: hello world how are you? Nothing too ground breaking here, but pay close attention to the exact way we wrote the program. In particular, notice how we lay out the periods, parentheses, and quotation marks. We'll also terminate lines with semicolons (;). Depending on how you structure your code, sometimes you'll be able to omit semicolons at the end of lines. For now, you'll want to include them just as we do. Syntax We refer to the exact arrangement of the symbols, characters, and keywords as syntax. These details matter — your computer will only be able to “understand” proper JavaScript syntax. A programming language is similar to a spoken language. A spoken language like English has grammar rules that we should follow in order to be understood by fellow speakers. In the same way, a programming language like JavaScript has syntax rules that we ought to follow! As you write your first lines of code in this new language, you may make many syntax errors. Don't get frustrated! This is normal — all new programmers go through this phase. Every time we recognize an error in our code, we have an opportunity to reinforce your understanding of correct syntax. Adopt a growth mindset and learn from your mistakes. Additionally, one of the best things about programming is that we can get such immediate feedback from our creations. There is no penalty for making a mistake when programming. Write some code, run the code, read the errors, fix the errors, rinse and repeat! Code comments Occasionally we'll want to leave comments or notes in our code. Commented lines will be ignored by our computer. This means that we can use comments to write plain english or temporarily avoid execution of some JavaScript lines. The proper syntax for writing a comment is to begin the line with double forward slashes (//):// let's write another program!!! console.log("hello world"); // console.log("how are you?"); console.log("goodbye moon"); The program above would only print: hello world goodbye moon Comments are useful when annotating pieces of code to offer an explanation of how the code works. We'll want to strive to write straightforward code that is self-explanatory when possible, but we can also use comments to add additional clarity. The real art of programming is to write code so elegantly that it is easy to follow. The Number Data Type The number data type in JS is used to represent any numerical values, including integers and decimal numbers. Basic Arithmetic Operators Operators are the symbols that perform particular operations.+ (addition)- (subtraction) asterisk (multiplication)/ (division)% (modulo) JS evaluates more complex expressions using the general math order of operations aka PEMDAS. PEMDAS : Parentheses, Exponents, Multiplication, Division, Modulo, Addition, Subtraction. To force a specific order of operation, use the group operator ( ) around a part of the expression. Modulo : Very useful operation to check divisibility of numbers, check for even & odd, whether a number is prime, and much more! (Discrete Math concept, circular problems can be solved with modulo) Whenever you have a smaller number % a larger number, the answer will just be the initial small number. console.log(7 % 10) // => 7; The String Data Type The string data type is a primitive data type that used to represent textual data. can be wrapped by either single or double quotation marks, best to choose one and stick with it for consistency. If your string contains quotation marks inside, can layer single or double quotation marks to allow it to work. “That's a great string”; (valid) 'Shakespeare wrote, “To be or not to be”'; (valid) 'That's a bad string'; (invalid) Alt. way to add other quotes within strings is to use template literals. `This is a temp'l'ate literal ${function}` // use ${} to invoke functions within..length : property that can be appended to data to return the length. empty strings have a length of zero. indices : indexes of data that begin at 0, can call upon index by using the bracket notation [ ]. console.log(“bootcamp”[0]); // => “b” console.log(“bootcamp”[10]); // => “undefined” console.log(“boots”[1 * 2]); // => “o” console.log(“boots”[“boot”.length-1]); // => “t” we can pass expressions through the brackets as well since JS always evaluates expressions first. The index of the last character of a string is always one less than it's length. indexOf() : method used to find the first index of a given character within a string. console.log(“bagel”.indexOf(“b”)); // => 0 console.log(“bagel”.indexOf(“z”)); // => -1 if the character inside the indexOf() search does not exist in the string, the output will be -1. the indexOf() search will return the first instanced index of the the char in the string. concatenate : word to describe joining strings together into a single string. The Boolean Data Type The Boolean data type is the simplest data type since there are only two values: true and false. Logical Operators (B oolean Operators) are used to establish logic in our code.! (not) : reverses a Boolean value. console.log(!true); // => false console.log(!!false); // => false Logical Order of Operations : JS will evaluate !, then &&, then ||. Short-Circuit Evaluation : Because JS evalutes from left to right, expressions can “short-circuit”. For example if we have true on the left of an || logical comparison, it will stop evaluating and yield true instead of wasting resources on processing the rest of the statement. console.log(true || !false) // => stops after it sees “true ||” Comparison Operators All comparison operators will result in a boolean output. The relative comparators> (greater than)< (less than)>= (greater than or equal to)<= (less than or equal to)=== (equal to)!== (not equal to) Fun Fact: “a” < “b” is considered valid JS Code because string comparisons are compared lexicographically (meaning dictionary order), so “a” is less than “b” because it appears earlier! If there is ever a standstill comparison of two string lexicographically (i.e. app vs apple) the comparison will deem the shorter string lesser. Difference between == and ====== Strict Equality, will only return true if the two comparisons are entirely the same.== Loose Equality, will return true even if the values are of a different type, due to coercion. (Avoid using this) Variables Variables are used to store information to be referenced and manipulated in a program. We initialize a variable by using the let keyword and a = single equals sign (assignment operator). let bootcamp = “App Academy”; console.log(bootcamp); // “App Academy” JS variable names can contain any alphanumeric characters, underscores, or dollar signs (cannot being with a number). If you do not declare a value for a variable, undefined is automatically set. let bootcamp; console.log(bootcamp); // undefined We can change the value of a previously declared variable (let, not const) by re-assigning it another value. let is the updated version of var; there are some differences in terms of hoisting and global/block scope Assignment Shorthand let num = 0; num += 10; // same as num = num + 10 num -= 2; // same as num = num — 2 num /= 4; // same as num = num / 4 num *= 7; // same as num = num * 7 In general, any nonsensical arithmetic will result in NaN ; usually operations that include undefined. Functions A function is a procedure of code that will run when called. Functions are used so that we do not have to rewrite code to do the same thing over and over. (Think of them as 'subprograms') Function Declaration : Process when we first initially write our function. Includes three things: Name of the function. A list of parameters () The code to execute {} Function Calls : We can call upon our function whenever and wherever* we want. (*wherever is only after the initial declaration) JS evaluates code top down, left to right. When we execute a declared function later on in our program we refer to this as invoking our function. Every function in JS returns undefined unless otherwise specified. When we hit a return statement in a function we immediately exit the function and return to where we called the function. When naming functions in JS always use camelCase and name it something appropriate. Greate code reads like English and almost explains itself. Think: Elegant, readable, and maintainable! Parameters and Arguments Parameters : Comma seperated variables specified as part of a function's declaration. Arguments : Values passed to the function when it is invoked. If the number of arguments passed during a function invocation is different than the number of paramters listed, it will still work. However, is there are not enough arguments provided for parameters our function will likely yield Nan. Including Comments Comments are important because they help other people understand what is going on in your code or remind you if you forgot something yourself. Keep in mind that they have to be marked properly so the browser won't try to execute them. In JavaScript you have two different options: Single-line comments — To include a comment that is limited to a single line, precede it with // Multi-line comments — In case you want to write longer comments between several lines, wrap it in /* and */ to avoid it from being executed Variables in JavaScript Variables are stand-in values that you can use to perform operations. You should be familiar with them from math class. var, const, let You have three different possibilities for declaring a variable in JavaScript, each with their own specialties: var — The most common variable. It can be reassigned but only accessed within a function. Variables defined with var move to the top when the code is executed. const — Can not be reassigned and not accessible before they appear within the code. let — Similar to const, the let variable can be reassigned but not re-declared. Data Types Variables can contain different types of values and data types. You use = to assign them: Numbers — var age = 23 Variables — var x Text (strings) — var a = "init" Operations — var b = 1 + 2 + 3 True or false statements — var c = true Constant numbers — const PI = 3.14 Objects — var name = {firstName:"John", lastName:"Doe"} There are more possibilities. Note that variables are case sensitive. That means lastname and lastName will be handled as two different variables. Objects Objects are certain kinds of variables. They are variables that can have their own values and methods. The latter are actions that you can perform on objects. var person = { firstName:”John”, lastName:”Doe”, age:20, nationality:”German”}; The Next Level: Arrays Next up in our JavaScript cheat sheet are arrays. Arrays are part of many different programming languages. They are a way of organizing variables and properties into groups. Here's how to create one in JavaScript: var fruit = [“Banana”, “Apple”, “Pear”]; Now you have an array called fruit which contains three items that you can use for future operations. Array Methods Once you have created arrays, there are a few things you can do with them: concat() — Join several arrays into one indexOf() — Returns the first position at which a given element appears in an array join() — Combine elements of an array into a single string and return the string lastIndexOf() — Gives the last position at which a given element appears in an array pop() — Removes the last element of an array push() — Add a new element at the end reverse() — Sort elements in a descending order shift() — Remove the first element of an array slice() — Pulls a copy of a portion of an array into a new array sort() — Sorts elements alphabetically splice() — Adds elements in a specified way and position toString() — Converts elements to strings unshift() —Adds a new element to the beginning valueOf() — Returns the primitive value of the specified object Operators If you have variables, you can use them to perform different kinds of operations. To do so, you need operators. Basic Operators+ — Addition- — Subtraction* — Multiplication/ — Division(...) — Grouping operator, operations within brackets are executed earlier than those outside% — Modulus (remainder )++ — Increment numbers-- — Decrement numbers Comparison Operators== — Equal to=== — Equal value and equal type!= — Not equal!== — Not equal value or not equal type> — Greater than< — Less than>= — Greater than or equal to<= — Less than or equal to? — Ternary operator Logical Operators&& — Logical and|| — Logical or! — Logical not Bitwise Operators& — AND statement| — OR statement~ — NOT^ — XOR<< — Left shift>> — Right shift>>> — Zero fill right shift Functions JavaScript functions are blocks of code that perform a certain task. A basic function looks like this: function name(parameter1, parameter2, parameter3) {// what the function does} As you can see, it consists of the function keyword plus a name. The function's parameters are in the brackets and you have curly brackets around what the function performs. You can create your own, but to make your life easier – there are also a number of default functions. Outputting Data A common application for functions is the output of data. For the output, you have the following options: alert() — Output data in an alert box in the browser window confirm() — Opens up a yes/no dialog and returns true/false depending on user click console.log() — Writes information to the browser console, good for debugging purposes document.write() — Write directly to the HTML document prompt() — Creates a dialogue for user input Global Functions Global functions are functions built into every browser capable of running JavaScript. decodeURI() — Decodes a Uniform Resource Identifier (URI) created by encodeURI or similar decodeURIComponent() — Decodes a URI component encodeURI() — Encodes a URI into UTF-8 encodeURIComponent() — Same but for URI components eval() — Evaluates JavaScript code represented as a string isFinite() — Determines whether a passed value is a finite number isNaN() — Determines whether a value is NaN or not Number() —- Returns a number converted from its argument parseFloat() — Parses an argument and returns a floating-point number parseInt() — Parses its argument and returns an integer JavaScript Loops Loops are part of most programming languages. They allow you to execute blocks of code desired number of times with different values: for (before loop; condition for loop; execute after loop) {// what to do during the loop} You have several parameters to create loops: for — The most common way to create a loop in JavaScript while — Sets up conditions under which a loop executes do while — Similar to the while loop but it executes at least once and performs a check at the end to see if the condition is met to execute again break —Used to stop and exit the cycle at certain conditions continue — Skip parts of the cycle if certain conditions are met If — Else Statements These types of statements are easy to understand. Using them, you can set conditions for when your code is executed. If certain conditions apply, something is done, if not — something else is executed. if (condition) {// what to do if condition is met} else {// what to do if condition is not met} A similar concept to if else is the switch statement. However, using the switch you select one of several code blocks to execute. Strings Strings are what JavaScript calls to text that does not perform a function but can appear on the screen. var person = “John Doe”; In this case, John Doe is the string. Escape Characters In JavaScript, strings are marked with single or double-quotes. If you want to use quotation marks in a string, you need to use special characters:\' — Single quote\" — Double quote Aside from that you also have additional escape characters:\\ — Backslash\b — Backspace\f — Form feed\n — New line\r — Carriage return\t — Horizontal tabulator\v — Vertical tabulator String Methods There are many different ways to work with strings: charAt() — Returns a character at a specified position inside a string charCodeAt() — Gives you the Unicode of a character at that position concat() — Concatenates (joins) two or more strings into one fromCharCode() — Returns a string created from the specified sequence of UTF-16 code units indexOf() — Provides the position of the first occurrence of a specified text within a string lastIndexOf() — Same as indexOf() but with the last occurrence, searching backward match() — Retrieves the matches of a string against a search pattern replace() — Find and replace specified text in a string search() — Executes a search for a matching text and returns its position slice() — Extracts a section of a string and returns it as a new string split() — Splits a string object into an array of strings at a specified position substr() — Similar to slice() but extracts a substring depending on a specified number of characters substring() — Also similar to slice() but can't accept negative indices toLowerCase() — Convert strings to lower case toUpperCase() — Convert strings to upper case valueOf() — Returns the primitive value (that has no properties or methods) of a string object Regular Expression Syntax Regular expressions are search patterns used to match character combinations in strings. The search pattern can be used for text search and text to replace operations. Pattern Modifiers e — Evaluate replacement i — Perform case-insensitive matching g — Perform global matching m — Perform multiple line matching s — Treat strings as a single line x — Allow comments and whitespace in the pattern U — Ungreedy pattern Brackets[abc] — Find any of the characters between the brackets[^abc] — Find any character which is not in the brackets[0-9] — Used to find any digit from 0 to 9[A-z] — Find any character from uppercase A to lowercase z(a|b|c) — Find any of the alternatives separated with | Metacharacters. — Find a single character, except newline or line terminator\w — Word character\W — Non-word character\d — A digit\D — A non-digit character\s — Whitespace character\S — Non-whitespace character\b — Find a match at the beginning/end of a word\B — A match not at the beginning/end of a word\0 — NUL character\n — A new line character\f — Form feed character\r — Carriage return character\t — Tab character\v — Vertical tab character\xxx — The character specified by an octal number xxx\xdd — Character specified by a hexadecimal number dd\uxxxx — The Unicode character specified by a hexadecimal number XXXX Quantifiers n+ — Matches any string that contains at least one n n* — Any string that contains zero or more occurrences of n n? — A string that contains zero or one occurrence of n n{X} — String that contains a sequence of X n's n{X,Y} — Strings that contain a sequence of X to Y n's n{X,} — Matches any string that contains a sequence of at least X n's n$ — Any string with n at the end of it^n — String with n at the beginning of it?=n — Any string that is followed by a specific string n?!n — String that is not followed by a specific string ni Numbers and Math In JavaScript, you can also work with numbers, constants and perform mathematical functions. Number Properties MAX_VALUE — The maximum numeric value representable in JavaScript MIN_VALUE — Smallest positive numeric value representable in JavaScript NaN — The “Not-a-Number” value NEGATIVE_INFINITY — The negative Infinity value POSITIVE_INFINITY — Positive Infinity value Number Methods toExponential() — Returns the string with a rounded number written as exponential notation toFixed() — Returns the string of a number with a specified number of decimals toPrecision() — String of a number written with a specified length toString() — Returns a number as a string valueOf() — Returns a number as a number Math Properties E — Euler's number LN2 — The natural logarithm of 2 LN10 — Natural logarithm of 10 LOG2E — Base 2 logarithm of E LOG10E — Base 10 logarithm of E PI — The number PI SQRT1_2 — Square root of 1/2 SQRT2 — The square root of 2 Math Methods abs(x) — Returns the absolute (positive) value of x acos(x) — The arccosine of x, in radians asin(x) — Arcsine of x, in radians atan(x) — The arctangent of x as a numeric value atan2(y,x) — Arctangent of the quotient of its arguments ceil(x) — Value of x rounded up to its nearest integer cos(x) — The cosine of x (x is in radians) exp(x) — Value of Ex floor(x) — The value of x rounded down to its nearest integer log(x) — The natural logarithm (base E) of x max(x,y,z,...,n) — Returns the number with the highest value min(x,y,z,...,n) — Same for the number with the lowest value pow(x,y) — X to the power of y random() — Returns a random number between 0 and 1 round(x) — The value of x rounded to its nearest integer sin(x) — The sine of x (x is in radians) sqrt(x) — Square root of x tan(x) — The tangent of an angle Dealing with Dates in JavaScript You can also work with and modify dates and time with JavaScript. This is the next chapter in the JavaScript cheat sheet. Setting Dates Date() — Creates a new date object with the current date and time Date(2017, 5, 21, 3, 23, 10, 0) — Create a custom date object. The numbers represent a year, month, day, hour, minutes, seconds, milliseconds. You can omit anything you want except for a year and month. Date("2017-06-23") — Date declaration as a string Pulling Date and Time Values getDate() — Get the day of the month as a number (1-31) getDay() — The weekday as a number (0-6) getFullYear() — Year as a four-digit number (yyyy) getHours() — Get the hour (0-23) getMilliseconds() — The millisecond (0-999) getMinutes() — Get the minute (0-59) getMonth() — Month as a number (0-11) getSeconds() — Get the second (0-59) getTime() — Get the milliseconds since January 1, 1970 getUTCDate() — The day (date) of the month in the specified date according to universal time (also available for day, month, full year, hours, minutes etc.) parse — Parses a string representation of a date and returns the number of milliseconds since January 1, 1970 Set Part of a Date setDate() — Set the day as a number (1-31) setFullYear() — Sets the year (optionally month and day) setHours() — Set the hour (0-23) setMilliseconds() — Set milliseconds (0-999) setMinutes() — Sets the minutes (0-59) setMonth() — Set the month (0-11) setSeconds() — Sets the seconds (0-59) setTime() — Set the time (milliseconds since January 1, 1970) setUTCDate() — Sets the day of the month for a specified date according to universal time (also available for day, month, full year, hours, minutes etc.) DOM Mode The DOM is the Document Object Model of a page. It is the code of the structure of a webpage. JavaScript comes with a lot of different ways to create and manipulate HTML elements (called nodes). Node Properties attributes — Returns a live collection of all attributes registered to an element baseURI — Provides the absolute base URL of an HTML element childNodes — Gives a collection of an element's child nodes firstChild — Returns the first child node of an element lastChild — The last child node of an element nextSibling — Gives you the next node at the same node tree level nodeName —Returns the name of a node nodeType — Returns the type of a node nodeValue — Sets or returns the value of a node ownerDocument — The top-level document object for this node parentNode — Returns the parent node of an element previousSibling — Returns the node immediately preceding the current one textContent — Sets or returns the textual content of a node and its descendants Node Methods appendChild() — Adds a new child node to an element as the last child node cloneNode() — Clones an HTML element compareDocumentPosition() — Compares the document position of two elements getFeature() — Returns an object which implements the APIs of a specified feature hasAttributes() — Returns true if an element has any attributes, otherwise false hasChildNodes() — Returns true if an element has any child nodes, otherwise false insertBefore() — Inserts a new child node before a specified, existing child node isDefaultNamespace() — Returns true if a specified namespaceURI is the default, otherwise false isEqualNode() — Checks if two elements are equal isSameNode() — Checks if two elements are the same node isSupported() — Returns true if a specified feature is supported on the element lookupNamespaceURI() — Returns the namespace URI associated with a given node lookupPrefix() — Returns a DOMString containing the prefix for a given namespace URI if present normalize() — Joins adjacent text nodes and removes empty text nodes in an element removeChild() — Removes a child node from an element replaceChild() — Replaces a child node in an element Element Methods getAttribute() — Returns the specified attribute value of an element node getAttributeNS() — Returns string value of the attribute with the specified namespace and name getAttributeNode() — Gets the specified attribute node getAttributeNodeNS() — Returns the attribute node for the attribute with the given namespace and name getElementsByTagName() — Provides a collection of all child elements with the specified tag name getElementsByTagNameNS() — Returns a live HTMLCollection of elements with a certain tag name belonging to the given namespace hasAttribute() — Returns true if an element has any attributes, otherwise false hasAttributeNS() — Provides a true/false value indicating whether the current element in a given namespace has the specified attribute removeAttribute() — Removes a specified attribute from an element removeAttributeNS() — Removes the specified attribute from an element within a certain namespace removeAttributeNode() — Takes away a specified attribute node and returns the removed node setAttribute() — Sets or changes the specified attribute to a specified value setAttributeNS() — Adds a new attribute or changes the value of an attribute with the given namespace and name setAttributeNode() — Sets or changes the specified attribute node setAttributeNodeNS() — Adds a new namespaced attribute node to an element Working with the User Browser Besides HTML elements, JavaScript is also able to take into account the user browser and incorporate its properties into the code. Window Properties closed — Checks whether a window has been closed or not and returns true or false defaultStatus — Sets or returns the default text in the status bar of a window document — Returns the document object for the window frames — Returns all <iframe> elements in the current window history — Provides the History object for the window innerHeight — The inner height of a window's content area innerWidth — The inner width of the content area length — Find out the number of <iframe> elements in the window location — Returns the location object for the window name — Sets or returns the name of a window navigator — Returns the Navigator object for the window opener — Returns a reference to the window that created the window outerHeight — The outer height of a window, including toolbars/scrollbars outerWidth — The outer width of a window, including toolbars/scrollbars pageXOffset — Number of pixels the current document has been scrolled horizontally pageYOffset — Number of pixels the document has been scrolled vertically parent — The parent window of the current window screen — Returns the Screen object for the window screenLeft — The horizontal coordinate of the window (relative to the screen) screenTop — The vertical coordinate of the window screenX — Same as screenLeft but needed for some browsers screenY — Same as screenTop but needed for some browsers self — Returns the current window status — Sets or returns the text in the status bar of a window top — Returns the topmost browser window Window Methods alert() — Displays an alert box with a message and an OK button blur() — Removes focus from the current window clearInterval() — Clears a timer set with setInterval() clearTimeout() — Clears a timer set with setTimeout() close() — Closes the current window confirm() — Displays a dialogue box with a message and an OK and Cancel button focus() — Sets focus to the current window moveBy() — Moves a window relative to its current position moveTo() — Moves a window to a specified position open() — Opens a new browser window print() — Prints the content of the current window prompt() — Displays a dialogue box that prompts the visitor for input resizeBy() — Resizes the window by the specified number of pixels resizeTo() — Resizes the window to a specified width and height scrollBy() — Scrolls the document by a specified number of pixels scrollTo() — Scrolls the document to specified coordinates setInterval() — Calls a function or evaluates an expression at specified intervals setTimeout() — Calls a function or evaluates an expression after a specified interval stop() — Stops the window from loading Screen Properties availHeight — Returns the height of the screen (excluding the Windows Taskbar) availWidth — Returns the width of the screen (excluding the Windows Taskbar) colorDepth — Returns the bit depth of the color palette for displaying images height — The total height of the screen pixelDepth — The color resolution of the screen in bits per pixel width — The total width of the screen JavaScript Events Events are things that can happen to HTML elements and are performed by the user. The programming language can listen for these events and trigger actions in the code. No JavaScript cheat sheet would be complete without them. Mouse onclick — The event occurs when the user clicks on an element oncontextmenu — User right-clicks on an element to open a context menu ondblclick — The user double-clicks on an element onmousedown — User presses a mouse button over an element onmouseenter — The pointer moves onto an element onmouseleave — Pointer moves out of an element onmousemove — The pointer is moving while it is over an element onmouseover — When the pointer is moved onto an element or one of its children onmouseout — User moves the mouse pointer out of an element or one of its children onmouseup — The user releases a mouse button while over an element Keyboard onkeydown — When the user is pressing a key down onkeypress — The moment the user starts pressing a key onkeyup — The user releases a key Frame onabort — The loading of a media is aborted onbeforeunload — Event occurs before the document is about to be unloaded onerror — An error occurs while loading an external file onhashchange — There have been changes to the anchor part of a URL onload — When an object has loaded onpagehide — The user navigates away from a webpage onpageshow — When the user navigates to a webpage onresize — The document view is resized onscroll — An element's scrollbar is being scrolled onunload — Event occurs when a page has unloaded Form onblur — When an element loses focus onchange — The content of a form element changes (for <input>, <select> and <textarea>) onfocus — An element gets focus onfocusin — When an element is about to get focus onfocusout — The element is about to lose focus oninput — User input on an element oninvalid — An element is invalid onreset — A form is reset onsearch — The user writes something in a search field (for <input="search">) onselect — The user selects some text (for <input> and <textarea>) onsubmit — A form is submitted Drag ondrag — An element is dragged ondragend — The user has finished dragging the element ondragenter — The dragged element enters a drop target ondragleave — A dragged element leaves the drop target ondragover — The dragged element is on top of the drop target ondragstart — User starts to drag an element ondrop — Dragged element is dropped on the drop target Clipboard oncopy — User copies the content of an element oncut — The user cuts an element's content onpaste — A user pastes the content in an element Media onabort — Media loading is aborted oncanplay — The browser can start playing media (e.g. a file has buffered enough) oncanplaythrough — The browser can play through media without stopping ondurationchange — The duration of the media changes onended — The media has reached its end onerror — Happens when an error occurs while loading an external file onloadeddata — Media data is loaded onloadedmetadata — Metadata (like dimensions and duration) are loaded onloadstart — The browser starts looking for specified media onpause — Media is paused either by the user or automatically onplay — The media has been started or is no longer paused onplaying — Media is playing after having been paused or stopped for buffering onprogress — The browser is in the process of downloading the media onratechange — The playing speed of the media changes onseeked — User is finished moving/skipping to a new position in the media onseeking — The user starts moving/skipping onstalled — The browser is trying to load the media but it is not available onsuspend — The browser is intentionally not loading media ontimeupdate — The playing position has changed (e.g. because of fast forward) onvolumechange — Media volume has changed (including mute) onwaiting — Media paused but expected to resume (for example, buffering) Animation animationend — A CSS animation is complete animationiteration — CSS animation is repeated animationstart — CSS animation has started Other transitionend — Fired when a CSS transition has completed onmessage — A message is received through the event source onoffline — The browser starts to work offline ononline — The browser starts to work online onpopstate — When the window's history changes onshow — A <menu> element is shown as a context menu onstorage — A Web Storage area is updated ontoggle — The user opens or closes the <details> element onwheel — Mouse wheel rolls up or down over an element ontouchcancel — Screen-touch is interrupted ontouchend — User's finger is removed from a touch-screen ontouchmove — A finger is dragged across the screen ontouchstart — A finger is placed on the touch-screen Errors When working with JavaScript, different errors can occur. There are several ways of handling them: try — Lets you define a block of code to test for errors catch — Set up a block of code to execute in case of an error throw — Create custom error messages instead of the standard JavaScript errors finally — Lets you execute code, after try and catch, regardless of the result Error Name Values JavaScript also has a built-in error object. It has two properties: name — Sets or returns the error name message — Sets or returns an error message in a string from The error property can return six different values as its name: EvalError — An error has occurred in the eval() function RangeError — A number is “out of range” ReferenceError — An illegal reference has occurred SyntaxError — A syntax error has occurred TypeError — A type error has occurred URIError — An encodeURI() error has occurred Explicit Conversions The simplest way to perform an explicit type conversion is to use the Boolean(), Number(), and String() functions. Any value other than null or undefined has a toString() method. n.toString(2); binary n.toString(8); octal n.toString(16); hex let n = 123456.789; n.toFixed(0)“123457” n.toFixed(5)“123456.78900” n.toExponential(3)“1.235e+5” n.toPrecision(7)“123456.8” n.toPrecision(10)“123456.7890” parseInt("3 blind mice") 3 parseFloat(" 3.14 meters") 3.14 parseInt("-12.34")-12 parseInt("0xFF") 255 Types, Values, and Variables Links Resource URL MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript Run Snippets https://developers.google.com/web/tools/chrome-devtools/javascript/snippets Explicit Conversions The simplest way to perform an explicit type conversion is to use the Boolean(), Number(), and String() functions. Any value other than null or undefined has a toString() method. n.toString(2); binary n.toString(8); octal n.toString(16); hex let n = 123456.789; n.toFixed(0)“123457” n.toFixed(5)“123456.78900” n.toExponential(3)“1.235e+5” n.toPrecision(7)“123456.8” n.toPrecision(10)“123456.7890” parseInt("3 blind mice") 3 parseFloat(" 3.14 meters") 3.14 parseInt("-12.34")-12 parseInt("0xFF") 255 parseInt("0xff") 255 parseInt("-0XFF")-255 parseInt("0.1") 0 parseInt(".1") NaN: integers can't start with “.” parseFloat("$72.47") NaN: numbers can't start with “$” Supply Radix parseInt("11", 2) 3 parseInt("ff", 16) 255 parseInt("077", 8) 63 Conversion Idioms x + "" String(x)+x Number(x) x-0 Number(x)!!x Boolean(x) Destructuring Assignment let [x,y] = [1,2]; let x=1, y=2[x,y] = [x + 1,y + 1]; x = x + 1, y = y + 1[x,y] = [y,x]; Swap the value of the two variables Destructuring assignment makes it easy to work with functions that return arrays of values: let [r,theta] = toPolar(1.0, 1.0); function toPolar(x, y) { return [Math.sqrt(x*x+y*y), Math.atan2(y,x)]; } Variable destructuring in loops: let o = { x: 1, y: 2 }; for(const [name, value] of Object.entries(o)) { console.log(name, value); // Prints "x 1" and "y 2" } Note: The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop. (The only important difference is that a for...in loop enumerates properties in the prototype chain as well). The list of variables on the left can include extra commas to skip certain values on the right[,x,,y] = [1,2,3,4]; x == 2; y == 4 Note: the last comma does not stand for a value. To collect all unused or remaining values into a single variable when destructuring an array, use three dots (...) before the last variable name on the left-hand side let [x, ...y] = [1,2,3,4]; y == [2,3,4] let [first, ...rest] = "Hello"; first == “H”; rest ==[“e”,”l”,”l”,”o”] Destructuring assignment can also be performed when the righthand side is an object value. let transparent = {r: 0.0, g: 0.0, b: 0.0, a: 1.0}; let {r, g, b} = transparent; r == 0.0; g == 0.0; b == 0.0 const {sin, cos, tan} = Math; sin=Math.sin, cos=Math.cos, tan=Math.tan Expressions and Operators In JavaScript, the values null and undefined are the only two values that do not have properties. In a regular property access expression using . or [], you get a TypeError if the expression on the left evaluates to null or undefined. You can use ?. and ?.[] syntax to guard against errors of this type. You can also invoke a function using ?.() instead of (). With the new ?.() invocation syntax, if the expression to the left of the ?. evaluates to null or undefined, then the entire invocation expression evaluates to undefined and no exception is thrown. Write the function invocation using ?.(), knowing that invocation will only happen if there is actually a value to be invoked function square(x, log) { log?.(x); // Call the function if there is one return x * x; } Note that expression x++ is not always the same as x = x + 1.The ++ operator never performs string concatenation: it always converts its operand to a number and increments it. If x is the string "1", ++x is the number 2, but x + 1 is the string "11". JavaScript objects are compared by reference, not by value. An object is equal to itself, but not to any other object. If two distinct objects have the same number of properties, with the same names and values, they are still not equal. Similarly, two arrays that have the same elements in the same order are not equal to each other. NaN value is never equal to any other value, including itself! To check whether a value x is NaN, use x !==, or the global isNaN() function. If both values refer to the same object, array, or function, they are equal. If they refer to different objects, they are not equal, even if both objects have identical properties. Evaluating Expressions JavaScript has the ability to interpret strings of JavaScript source code, evaluating them to produce a value. eval("3+2") Because of security issues, some web servers use the HTTP “Content-Security-Policy” header to disable eval() for an entire website. First-Defined (??) The first-defined operator ?? evaluates to its first defined operand: if its left operand is not null and not undefined, it returns that value. a ?? b is equivalent to (a !== null && a !== undefined) ? a : b?? is a useful alternative to ||. The problem with this idiomatic use is that zero, the empty string, and false are all falsy values that may be perfectly valid in some circumstances. In this code example, if maxWidth is zero, that value will be ignored. But if we change the || operator to ??, we end up with an expression where zero is a valid value.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Interviewing Navigation🏡 Home🗺 Navigation📥 Useful Downloads🛠 Skills My Stack🙏 Resources Orientation: Links Practice Problems:❄ Cold Outreach Generator Running List Of MISC Resources: Resume📰 Resume Examples Advice Cover Letter📒 Cover Letter Example Of Developer Bio Portfolio💼 Showcase💾 Git Repo🖼 Portfolio📈 Slack&Lambda📍 Pinned Items:📌 Pinned Messages:❇ Slack Announcements📺 Recordings🧑🤝🧑 People Aux-Resources Youtube🖋 Interview Prep⁉ Interview Questions. Cheat Sheets Python-VS-JS Cheat Sheet Common Knowledge Questions Types Of Data Structures👨💻 Leetcode: Hash Tables DS_ALGO Practice: Python Subpage🐍 Python More Practice: Tutorials Job Search Guide Common Questions Self Introduction Getting Started Applications & Job Postings👔 Postings: My Applications😅 Jobs I Really Want Stackbit Developer Advocate (Remote) Page 4 Emails Job Boards📋 Job Boards Less Promising Job Boards LIST OF BOARDS Networking🗓 Events Lambda Guidance & Meetings📥 Meetings: MISC🗞 Articles To Read Notes📓 Notes Page 5🖨 Interviewing General🖥 JS Job Search Navigation Review Of Concepts
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Interactive Data Structures Interactive Games Embeds Callstack Visualizer Jupyter Notebooks Zumzi Video Conferencing (Mesibo API Backend) Other Websites Clock Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    my gists Gist Archive Gist Archive Featured Gists: const Promise = require("bluebird"); const fs = Promise.promisifyAll(require("fs")); const crypto = require("crypto"); const path = require("path"); const pathA = "."; const pathB = "/path/to/the/directory/you/want/to/compare/it/to"; let hashes = []; function hashDirIn(folder) { var pathPromiseA = fs .readdirAsync(folder) .map(function (fileName) { var workPath = path.join(folder, fileName); var statPromise = fs.statAsync(workPath); return Promise.join( statPromise, fileName, function (statPromise, fileName) { if (statPromise.isFile()) { function makeStream(file, callback) { var result = fs.createReadStream(workPath); return callback(result); } function process(stream) { var hash = crypto.createHash("md5"); return new Promise(function (resolve, reject) { stream.on("data", function updateProcess(chunk) { hash.update(chunk, "utf8"); }); stream.on("end", resolve); }).then(function publish() { var digest = hash.digest("hex"); hashes.push({ digest: digest, path: workPath }); }); } return makeStream(fileName, process); } } ); }) .then(function () { if (i == 1) { hashes.sort(function (a, b) { if (a.digest < b.digest) { return -1; } if (a.digest > b.digest) { return 1; } return 0; }); var dupe = 1; hashes.map(function (obj, index) { if (index - 1 >= 0) { if (obj.digest == hashes[index - 1].digest) { console.log("Dupe " + dupe + " found:"); console.log(obj.path); console.log("Equal to:"); console.log(hashes[index - 1].path + "\n"); dupe++; } } }); } i++; }); } var i = 0; hashDirIn(pathA); hashDirIn(pathB); will replace any spaces in file names with an underscore! for file in *; do mv "$file" `echo $file | tr ' ' '_'` ; done ## TAKING IT A STEP FURTHER: # Let's do it recursivley: function RecurseDirs () { oldIFS=$IFS IFS=$'\n' for f in "$@" do # YOUR CODE HERE! [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)] for file in \*; do mv "$file" `echo $file | tr ' ' '_'` ; done if [[ -d "${f}" ]]; then cd "${f}" RecurseDirs $(ls -1 ".") cd .. fi done IFS=$oldIFS } RecurseDirs "./" Copy to clipboard jQuerry Language: Javascript/Jquery In combination with the script tag : , this snippet will add a copy to clipboard button to all of your embedded blocks.$(document).ready(function () { $("code, pre").append( '<span class="command-copy" ><i class="fa fa-clipboard" aria-hidden="true"></i></span>' ); $("code span.command-copy").click(function (e) { var text = $(this).parent().text().trim(); //.text(); var copyHex = document.createElement("input"); copyHex.value = text; document.body.appendChild(copyHex); copyHex.select(); document.execCommand("copy"); console.log(copyHex.value); document.body.removeChild(copyHex); }); $("pre span.command-copy").click(function (e) { var text = $(this).parent().text().trim(); var copyHex = document.createElement("input"); copyHex.value = text; document.body.appendChild(copyHex); copyHex.select(); document.execCommand("copy"); console.log(copyHex.value); document.body.removeChild(copyHex); }); }); Append Files in PWD//APPEND-DIR.js const fs = require("fs"); let cat = require("child_process").execSync("cat *").toString("UTF-8"); fs.writeFile("output.md", cat, (err) => { if (err) throw err; }); doesUserFrequentStarbucks.js const isAppleDevice = /Mac|iPod|iPhone|iPad/.test(navigator.platform); console.log(isAppleDevice); // Result: will return true if user is on an Apple device arr-intersection.js/* function named intersection(firstArr) that takes in an array and returns a function. When the function returned by intersection is invoked passing in an array (secondArr) it returns a new array containing the elements common to both firstArr and secondArr. */ function intersection(firstArr) { return (secondArr) => { let common = []; for (let i = 0; i < firstArr.length; i++) { let el = firstArr[i]; if (secondArr.indexOf(el) > -1) { common.push(el); } } return common; }; } let abc = intersection(["a", "b", "c"]); // returns a function console.log(abc(["b", "d", "c"])); // returns [ 'b', 'c' ] let fame = intersection(["f", "a", "m", "e"]); // returns a function console.log(fame(["a", "f", "z", "b"])); // returns [ 'f', 'a' ] arr-of-cum-partial-sums.js/* First is recurSum(arr, start) which returns the sum of the elements of arr from the index start till the very end. Second is partrecurSum() that recursively concatenates the required sum into an array and when we reach the end of the array, it returns the concatenated array. */ //arr.length -1 = 5 // arr [ 1, 7, 12, 6, 5, 10 ] // ind [ 0 1 2 3 4 5 ] // ↟ ↟ // start end function recurSum(arr, start = 0, sum = 0) { if (start < arr.length) { return recurSum(arr, start + 1, sum + arr[start]); } return sum; } function rPartSumsArr(arr, partSum = [], start = 0, end = arr.length - 1) { if (start <= end) { return rPartSumsArr( arr, partSum.concat(recurSum(arr, start)), ++start, end ); } return partSum.reverse(); } console.log( "------------------------------------------------rPartSumArr------------------------------------------------" ); console.log("rPartSumsArr(arr)=[ 1, 1, 5, 2, 6, 10 ]: ", rPartSumsArr(arr)); console.log("rPartSumsArr(arr1)=[ 1, 7, 12, 6, 5, 10 ]: ", rPartSumsArr(arr1)); console.log( "------------------------------------------------rPartSumArr------------------------------------------------" ); /* ------------------------------------------------rPartSumArr------------------------------------------------ rPartSumsArr(arr)=[ 1, 1, 5, 2, 6, 10 ]: [ 10, 16, 18, 23, 24, 25 ] rPartSumsArr(arr1)=[ 1, 7, 12, 6, 5, 10 ]: [ 10, 15, 21, 33, 40, 41 ] ------------------------------------------------rPartSumArr------------------------------------------------ */ camel2Kabab.js function camelToKebab(value) { return value.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); } camelCase.js function camel(str) { return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) { if (+match === 0) return ""; // or if (/\s+/.test(match)) for white spaces return index === 0 ? match.toLowerCase() : match.toUpperCase(); }); } concatLinkedLists.js function addTwoNumbers(l1, l2) { let result = new ListNode(0); let currentNode = result; let carryOver = 0; while (l1 != null || l2 != null) { let v1 = 0; let v2 = 0; if (l1 != null) v1 = l1.val; if (l2 != null) v2 = l2.val; let sum = v1 + v2 + carryOver; carryOver = Math.floor(sum / 10); sum = sum % 10; currentNode.next = new ListNode(sum); currentNode = currentNode.next; if (l1 != null) l1 = l1.next; if (l2 != null) l2 = l2.next; } if (carryOver > 0) { currentNode.next = new ListNode(carryOver); } return result.next; } fast-is-alpha-numeric.js//Function to test if a character is alpha numeric that is faster than a regular //expression in JavaScript let isAlphaNumeric = (char) => { char = char.toString(); let id = char.charCodeAt(0); if ( !(id > 47 && id < 58) && // if not numeric(0-9) !(id > 64 && id < 91) && // if not letter(A-Z) !(id > 96 && id < 123) // if not letter(a-z) ) { return false; } return true; }; console.log(isAlphaNumeric("A")); //true console.log(isAlphaNumeric(2)); //true console.log(isAlphaNumeric("z")); //true console.log(isAlphaNumeric(" ")); //false console.log(isAlphaNumeric("!")); //false find-n-replace.js function replaceWords(str, before, after) { if (/^[A-Z]/.test(before)) { after = after[0].toUpperCase() + after.substring(1); } else { after = after[0].toLowerCase() + after.substring(1); } return str.replace(before, after); } console.log(replaceWords("Let us go to the store", "store", "mall")); //"Let us go to the mall" console.log(replaceWords("He is Sleeping on the couch", "Sleeping", "sitting")); //"He is Sitting on the couch" console.log(replaceWords("His name is Tom", "Tom", "john")); //"His name is John" flatten-arr.js/*Simple Function to flatten an array into a single layer */ const flatten = (array) => array.reduce( (accum, ele) => accum.concat(Array.isArray(ele) ? flatten(ele) : ele), [] ); isWeekDay.js const isWeekday = (date) => date.getDay() % 6 !== 0; console.log(isWeekday(new Date(2021, 0, 11))); // Result: true (Monday) console.log(isWeekday(new Date(2021, 0, 10))); // Result: false (Sunday) longest-common-prefix.js function longestCommonPrefix(strs) { let prefix = ""; if (strs.length === 0) return prefix; for (let i = 0; i < strs[0].length; i++) { const character = strs[0][i]; for (let j = 0; j < strs.length; j++) { if (strs[j][i] !== character) return prefix; } prefix = prefix + character; } return prefix; }
    https://bgoonz-blog.netlify.app/images/code.png
  • FAQ
    FAQ What's the most useful business-related book you've ever read? A Random Walk Down Wall Street What's your favorite non-business book? Hitchhiker's Guide To The Galaxy If money were not an issue, what would you be doing right now? Designing recording software/hardware and using it What words of advice would you give your younger self? Try harder and listen to your parents more (the latter bit of advice would be almost certain to fall on deaf ears lol) What's the most creative thing you've ever done? I built a platform that listens to a guitarist's performance and automatically triggers guitar effects at the appropriate time in the song. Which founders or startups do you most admire? Is it to basic to say Tesla... I know they're prevalent now but I've been an avid fan since as early as 2012. What's your super power? Having really good ideas and forgetting them moments later. What's the best way for people to get in touch with you? A text What aspects of your work are you most passionate about? Creating things that change my every day life. What was the most impactful class you took in school? Modern Physics... almost changed my major after that class... but at the end of the day engineering was a much more fiscally secure avenue. What's something you wish you had done years earlier? Learned to code ... and sing What words of wisdom do you live by?*Disclaimer: The following wisdom is very cliche ... but... "Be the change that you wish to see in the world." Plug-ins Contact!
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Docs My DevDocs Deploy/job-hunt//notes-template///showcase//blog//review//blog/blog-archive//blog/my-medium//blog/blogwcomments//blog/data-structures//docs/gallery//blog/python-for-js-dev//blog/platform-docs//docs/sitemap//docs/about/me//blog/python-resources//docs/about/resume//docs//blog/web-scraping//docs/about//docs/articles/algo//docs/articles/install//docs/articles//docs/articles/gallery//docs/articles/intro//docs/articles/basic-web-dev//docs/articles/reading-files//docs/articles/writing-files//docs/audio/audio//docs/content/projects//docs/audio/terms//docs/faq//docs/community//docs/articles/resources//docs/content//docs/docs/git-repos//docs/content/trouble-shooting//docs/articles/python//docs/interact/clock//docs/docs/python//docs/interact/jupyter-notebooks//docs/interact//docs/faq/contact//docs/quick-reference/docs//docs/interact/other-sites//docs/quick-reference/new-repo-instructions//docs/quick-reference/Emmet//docs/quick-reference/installation//docs/quick-reference/vscode-themes//docs/react/createReactApp//docs/react/react2//docs/quick-reference//docs/react//docs/tools//docs/tools/notes-template//docs/tools/more-tools//docs/tools/plug-ins//docs/articles/node/install//docs/tools/vscode//docs/articles/node/intro//docs/articles/node/nodejs//docs/articles/node/nodevsbrowser//docs/articles/node/npm//docs/articles/node/reading-files//docs/articles/node/writing-files//docs/react-in-depth//docs/articles/article-compilation//docs/medium/my-websites//docs/medium/social//docs/medium/medium-links//docs/medium/ Apendix Data Structures Docs ECMAScript 6 Learn Css Git Repo List Markdown Git Reference lorem-ipsum Sitemap Regular Expressions Useful Snippets Bash Commands That Save Me Time and Frustration HTML SPEC lorem-ipsum Node Docs
    https://bgoonz-blog.netlify.app/images/code.png
  • Data Structures
    Data Structures Fundamental Data Structures In JavaScript Data structures in JavaScript CODEX Fundamental Data Structures In JavaScript Data structures in JavaScript H ere’s a website I created to practice data structures! directory Edit description ds-algo-official-c3dw6uapg-bgoonz.vercel.app H ere’s the repo that the website is built on: bgoonz/DS-ALGO-OFFICIAL Navigation ####Author:Bryan Guner Big O notation is the language we use for talking about how long an algorithm takes… github.com H ere’s a live code editor where you can mess with any of the examples… Resources (article content below): Videos Abdul Bari: YouTubeChannel for Algorithms Data Structures and algorithms Data Structures and algorithms Course Khan Academy Data structures by mycodeschool Pre-requisite for this lesson is good understanding of pointers in C. MIT 6.006: Intro to Algorithms(2011) Data Structures and Algorithms by Codewithharry Books Introduction to Algorithms by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein Competitive Programming 3 by Steven Halim and Felix Halim Competitive Programmers Hand Book Beginner friendly hand book for competitive programmers. Data Structures and Algorithms Made Easy by Narasimha Karumanchi Learning Algorithms Through Programming and Puzzle Solving by Alexander Kulikov and Pavel Pevzner Coding practice LeetCode InterviewBit Codility HackerRank Project Euler Spoj Google Code Jam practice problems HackerEarth Top Coder CodeChef Codewars CodeSignal CodeKata Firecode Courses Master the Coding Interview: Big Tech (FAANG) Interviews Course by Andrei and his team. Common Python Data Structures Data structures are the fundamental constructs around which you build your programs. Each data structure provides a particular way of organizing data so it can be accessed efficiently, depending on your use case. Python ships with an extensive set of data structures in its standard library. Fork CPP A good course for beginners. EDU Advanced course. C++ For Programmers Learn features and constructs for C++. Guides GeeksForGeeks — A CS portal for geeks Learneroo — Algorithms Top Coder tutorials Infoarena training path (RO) Steven & Felix Halim — Increasing the Lower Bound of Programming Contests (UVA Online Judge) space The space complexity represents the memory consumption of a data structure. As for most of the things in life, you can’t have it all, so it is with the data structures. You will generally need to trade some time for space or the other way around. time The time complexity for a data structure is in general more diverse than its space complexity. Several operations In contrary to algorithms, when you look at the time complexity for data structures you need to express it for several operations that you can do with data structures. It can be adding elements, deleting elements, accessing an element or even searching for an element. Dependent on data Something that data structure and algorithms have in common when talking about time complexity is that they are both dealing with data. When you deal with data you become dependent on them and as a result the time complexity is also dependent of the data that you received. To solve this problem we talk about 3 different time complexity. The best-case complexity: when the data looks the best The worst-case complexity: when the data looks the worst The average-case complexity: when the data looks average Big O notation The complexity is usually expressed with the Big O notation. The wikipedia page about this subject is pretty complex but you can find here a good summary of the different complexity for the most famous data structures and sorting algorithms. The Array data structure### Definition An Array data structure, or simply an Array, is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key. The simplest type of data structure is a linear array, also called one-dimensional array. From Wikipedia Arrays are among the oldest and most important data structures and are used by every program. They are also used to implement many other data structures. Complexity Average Access Search Insertion Deletion O(1) O(n) O(1) O(n) indexvalue0 … this is the first value, stored at zero position The index of an array runs in sequence This could be useful for storing data that are required to be ordered, such as rankings or queues In JavaScript, array’s value could be mixed; meaning value of each index could be of different data, be it String, Number or even Objects 2. Objects Think of objects as a logical grouping of a bunch of properties. Properties could be some variable that it’s storing or some methods that it’s using. I also visualize an object as a table. The main difference is that object’s “index” need not be numbers and is not necessarily sequenced. The Hash Table### *Definition* A Hash Table (Hash Map) is a data structure used to implement an associative array, a structure that can map keys to values. A Hash Table uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found. From Wikipedia Hash Tables are considered the more efficient data structure for lookup and for this reason, they are widely used. Complexity Average Access Search Insertion Deletion O(1) O(1) O(1) The code Note, here I am storing another object for every hash in my Hash Table. The Set Sets Sets are pretty much what it sounds like. It’s the same intuition as Set in Mathematics. I visualize Sets as Venn Diagrams.### *Definition* A Set is an abstract data type that can store certain values, without any particular order, and no repeated values. It is a computer implementation of the mathematical concept of a finite Set. From Wikipedia The Set data structure is usually used to test whether elements belong to set of values. Rather then only containing elements, Sets are more used to perform operations on multiple values at once with methods such as union, intersect, etc… Complexity Average Access Search Insertion Deletion O(n) O(n) O(n) The code The Singly Linked List### *Definition* A Singly Linked List is a linear collection of data elements, called nodes pointing to the next node by means of pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence. Linked Lists are among the simplest and most common data structures because it allows for efficient insertion or removal of elements from any position in the sequence. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code The Doubly Linked List### *Definition* A Doubly Linked List is a linked data structure that consists of a set of sequentially linked records called nodes. Each node contains two fields, called links, that are references to the previous and to the next node in the sequence of nodes. From Wikipedia Having two node links allow traversal in either direction but adding or removing a node in a doubly linked list requires changing more links than the same operations on a Singly Linked List. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code The Stack Definition A Stack is an abstract data type that serves as a collection of elements, with two principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed. The order in which elements come off a Stack gives rise to its alternative name, LIFO (for last in, first out). From Wikipedia A Stack often has a third method peek which allows to check the last pushed element without popping it. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code The Queue### *Definition* A Queue is a particular kind of abstract data type or collection in which the entities in the collection are kept in order and the principal operations are the addition of entities to the rear terminal position, known as enqueue, and removal of entities from the front terminal position, known as dequeue. This makes the Queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the Queue will be the first one to be removed. As for the Stack data structure, a peek operation is often added to the Queue data structure. It returns the value of the front element without dequeuing it. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(n) The code The Tree### *Definition* A Tree is a widely used data structure that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node. A tree data structure can be defined recursively as a collection of nodes (starting at a root node), where each node is a data structure consisting of a value, together with a list of references to nodes (the “children”), with the constraints that no reference is duplicated, and none points to the root node. From Wikipedia Complexity Average Access Search Insertion Deletion O(n) O(n) O(n) O(n) To get a full overview of the time and space complexity of the Tree data structure, have a look to this excellent Big O cheat sheet.*The code* The Graph### *Definition* A Graph data structure consists of a finite (and possibly mutable) set of vertices or nodes or points, together with a set of unordered pairs of these vertices for an undirected Graph or a set of ordered pairs for a directed Graph. These pairs are known as edges, arcs, or lines for an undirected Graph and as arrows, directed edges, directed arcs, or directed lines for a directed Graph. The vertices may be part of the Graph structure, or may be external entities represented by integer indices or references. A graph is any collection of nodes and edges. Much more relaxed in structure than a tree. It doesn’t need to have a root node (not every node needs to be accessible from a single node) It can have cycles (a group of nodes whose paths begin and end at the same node) Cycles are not always “isolated”, they can be one part of a larger graph. You can detect them by starting your search on a specific node and finding a path that takes you back to that same node. Any number of edges may leave a given node A Path is a sequence of nodes on a graph Cycle Visual A Graph data structure may also associate to each edge some edge value, such as a symbolic label or a numeric attribute (cost, capacity, length, etc.). Representation There are different ways of representing a graph, each of them with its own advantages and disadvantages. Here are the main 2: Adjacency list: For every vertex a list of adjacent vertices is stored. This can be viewed as storing the list of edges. This data structure allows the storage of additional data on the vertices and edges. Adjacency matrix: Data are stored in a two-dimensional matrix, in which the rows represent source vertices and columns represent destination vertices. The data on the edges and vertices must be stored externally. Graph The code If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz’s gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: Discover More: Web-Dev-Hub Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of… bgoonz-blog.netlify.app By Bryan Guner on March 5, 2021. Canonical link Exported from Medium on August 31, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Manage Content
    Close Menu Content # My Repos: RECENT PROJECTS History API Trouble Shooting Archive Queries and Mutations (Gatsby) Algorithms & Data Structures Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Where To Get Support
    Community➤ Connect with me: GitHub Gitlab Bitbucket Medium code pen Replit Quora Redit webcomponents.dev dev.to runkit Observable Notebooks npm stack-exchange Observable Notebooks Upwork Notion AngelList StackShare Plunk giphy kofi Codewars Dribble Glitch contentful Netlify Stackblitz Vercel Youtube wordpress Edabit Vinmeo js fiddle Google Developer Profile Gittee Wakatime Tweets by bgooonz New Developers Video Chat
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Career Job Search Docs: Job Search Gitbook Docs Job Board Developer Interview Questions Do & Don't of Interviewing!
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Audio Audio Feature Extraction Audio Discrete Fast Fourier Transform dynamic-time-warping Dynamic Time Warping Algorithm Explained (Python) Web Apis Fast Fourier Transform Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Articles Articles The HTTP Protocol How The Web Works lorem-ipsum insert-into-array Sorting Algorithms Introduction to npm lorem-ipsum The Uniform Resource Locator (URL) Web Design Firebase Web Standards Checklist lorem-ipsum Web Developer Tools where-is-npm-pack Node Export Module The-package-lock.json-file node-cli-args packagejson npm global or local packages Common Modules Dev Dependencies Node Buffers Web Dev Review The Node.js Event Loop Fs-Module Install Intro To Node Node Modules System Javascript and Node Node vs Browser The npx Node.js Package Runner OS-Module Reading Files Semantic Versioning Writing Files Node APIs With Express
    https://bgoonz-blog.netlify.app/images/code.png
  • About
    About Hi 👋, I'm Bryan Netlify Research Program Participant! WEBSITE ⇄ Portfolio ⇄ Collaborate ⇄ Other-Websites➤ Email bryan.guner@gmail.com Phone 551-254-5505 A passionate Web Developer, Electrical Engineer, Musician & Producer [![Bryans github activity graph](https://activity-graph.herokuapp.com/graph?username=bgoonz&custom_title=This%20is%20Bryans%20Activity&hide_border=true&theme=chartreuse-dark)](https://github.com/bgoonz/github-readme-activity-graph) Languages and Tools: About Me🔭 Contract Web Development Relational Concepts🌱 I'm currently learning React/Redux, Python, Java, Express, jQuery👯 I'm looking to collaborate on Any web audio or open source educational tools.🤝 I'm looking for help with Learning React👨‍💻 All of my projects are available at https://bgoonz.github.io/📝 I regularly write articles on medium && Web-Dev-Resource-Hub💬 Ask me about Anything:📫 How to reach me bryan.guner@gmail.com⚡ Fun fact I played Bamboozle Music Festival at the Meadowlands Stadium Complex when I was 14. i really like music :headphones: What's the most useful business-related book you've ever read? A Random Walk Down Wall Street What's your favorite non-business book? Hitchhiker's Guide To The Galaxy If money were not an issue, what would you be doing right now? Designing recording software/hardware and using it What words of advice would you give your younger self? Try harder and listen to your parents more (the latter bit of advice would be almost certain to fall on deaf ears lol) What's the most creative thing you've ever done? I built a platform that listens to a guitarist's performance and automatically triggers guitar effects at the appropriate time in the song. Which founders or startups do you most admire? Is it to basic to say Tesla... I know they're prevalent now but I've been an avid fan since as early as 2012. What's your super power? Having really good ideas and forgetting them moments later. What's the best way for people to get in touch with you? A text What aspects of your work are you most passionate about? Creating things that change my every day life. What was the most impactful class you took in school? Modern Physics... almost changed my major after that class... but at the end of the day engineering was a much more fiscally secure avenue. What's something you wish you had done years earlier? Learned to code ... and sing What words of wisdom do you live by?*Disclaimer: The following wisdom is very cliche ... but... "Be the change that you wish to see in the world." Mahatma Gandhi| | ## Portfolio: netlify || :------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Languages | | | Libraries | | | Frameworks | | | Databases | | | Testing | | | Other | | Resume ➤ Technical Skills­­­ Programming** Languages:** JavaScript ES-6, NodeJS, React, HTML5, CSS3, SCSS, Bash Shell, Excel, SQL, NoSQL, MATLAB, Python, C++ Databases: PostgreSQL, MongoDB Cloud: Docker, AWS, Google App Engine, Netlify, Digital Ocean, Heroku, Azure Cloud Services OS: Linux, Windows (WSL), IOS Agile: GitHub, BitBucket, Jira, Confluence IDEs: VSCode, Visual Studio, Atom, Code Blocks, Sublime Text 3, Brackets➤ Experience Relational Concepts: Hallandale Beach, FL March 2020 - Present Front End Web Developer Responsible for front-end development for a custom real estate application which provides sophisticated and fully customizable filtering to allow investors and real estate professionals to narrow in on exact search targets. Designed mock-up screens, wireframes, and workflows for intuitive user experience. Migrated existing multi-page user experience into singular page interfaces using React components. Participated in every stage of the design from conception through development and iterative improvement. Produced user stories and internal documentation for future site development and maintenance. Implemented modern frameworks including Bootstrap and Font-Awesome to give the site an aesthetic overhaul. Managed all test deployments using a combination of Digital Ocean and Netlify. Produced unit tests using a combination of Mocha and Chai. Injected Google Analytics to capture pertinent usage data to produce an insightful dashboard experience. Environment: JavaScript, JQuery, React, HTML5 & CSS, Bootstrap, DOJO, Google Cloud, Bash Script Cembre: Edison, NJ Nov 2019 – Mar 2020 Product Development Engineer Converted client's product needs into technical specs to be sent to the development team in Italy. Reorganized internal file server structure. Conducted remote / in person system integration and product demonstrations. Presided over internal and end user software trainings in addition to producing the corresponding documentation. Served as the primary point of contact for troubleshooting railroad hardware and software in the North America. Environment: Excel, AutoCAD, PowerPoint, Word➤ Education**B.S. Electrical Engineering, TCNJ, ** Ewing NJ 2014 – 2019 Capstone Project – Team Lead Successfully completed and delivered a platform to digitize a guitar signal and perform filtering before executing frequency & time domain analysis to track a current performance against prerecorded performance. Implemented the Dynamic Time Warping algorithm in C++ and Python to autonomously activate or adjust guitar effect at multiple pre-designated section of performance. Environment: C++, Python, MATLAB, PureData My Projects Project Name Skills used Description Web-Dev-Resource-Hub (blog) Html, Css, javascript, Python, jQuery, React, FireBase, AWS S3, Netlify, Heroku, NodeJS, PostgreSQL, C++, Web Audio API My blog site contains my resource sharing and blog site ... centered mostly on web development and just a bit of audio production / generally nerdy things I find interesting. Dynamic Guitar Effects Triggering Using A Modified Dynamic Time Warping Algorithm C, C++, Python, Java, Pure Data, Matlab Successfully completed and delivered a platform to digitize a guitar signal and perform filtering before executing frequency & time domain analysis to track a current performance against prerecorded performance.Implemented the Dynamic Time Warping algorithm in C++ and Python to autonomously activate or adjust guitar effect at multiple pre-designated section of performance. Data Structures & Algorithms Interactive Learning Site HTML, CSS, Javascript, Python, Java, jQuery, Repl.it-Database API A interactive and comprehensive guide and learning tool for DataStructures and Algorithms ... concentrated on JS but with some examples in Python, C++ and Java as well MihirBeg.com Html, Css, Javascript, Bootstrap, FontAwesome, jQuery A responsive and mobile friendly content promotion site for an Audio Engineer to engage with fans and potential clients Tetris-JS Html, Css, Javascript The classic game of tetris implemented in plain javascipt and styled with a retro-futureistic theme Git Html Preview Tool Git, Javascript, CSS3, HTML5, Bootstrap, BitBucket Loads HTML using CORS proxy, then process all links, frames, scripts and styles, and load each of them using CORS proxy, so they can be evaluated by the browser. Mini Project Showcase HTML, HTML5, CSS, CSS3, Javascript, jQuery add songs and play music, it also uses to store data in INDEXEDB Database by which we can play songs, if we not clear the catch then song will remain stored in database. Learning React Blog React Repo: React Repo react-documentation-site➤ Codepens (mostly embeded animations) code-pens-embedded➤ Weekly-Quick-Snips: Snippet of the Day: replaceAll the method string.replaceAll(search, replaceWith) replaces all appearances of search string with replaceWith. const str = 'this is a JSsnippets example'; const updatedStr = str.replace('example', 'snippet'); // 'this is a JSsnippets snippet' The tricky part is that replace method replaces only the very first match of the substring we have passed: const str = 'this is a JSsnippets example and examples are great'; const updatedStr = str.replace('example', 'snippet'); //'this is a JSsnippets snippet and examples are great' In order to go through this, we need to use a global regexp instead: const str = 'this is a JSsnippets example and examples are great'; const updatedStr = str.replace(/example/g, 'snippet'); //'this is a JSsnippets snippet and snippets are greatr' but now we have new friend in town, replaceAll const str = 'this is a JSsnippets example and examples are great'; const updatedStr = str.replaceAll('example', 'snippet'); //'this is a JSsnippets snippet and snippets are greatr' Fibonacci in Python: def fib_iter(n): if n == 0: return 0 if n == 1: return 1 p0 = 0 p1 = 1 for i in range(n-1): next_val = p0 + p1 p0 = p1 p1 = next_val return next_val for i in range(10): print(f'{i}: {fib_iter(i)}') Yesterday's Snippet of the day: def quicksort(l): # One of our base cases is an empty list or list with one element if len(l) == 0 or len(l) == 1: return l # If we have a left list, a pivot point and a right list... # assigns the return values of the partition() function left, pivot, right = partition(l) # Our sorted list looks like left + pivot + right, but sorted. # Pivot has to be in brackets to be a list, so python can concatenate all the elements to a single list return quicksort(left) + [pivot] + quicksort(right) print(quicksort([])) print(quicksort([1])) print(quicksort([1,2])) print(quicksort([2,1])) print(quicksort([2,2])) print(quicksort([5,3,9,4,8,1,7])) print(quicksort([1,2,3,4,5,6,7])) print(quicksort([9,8,7,6,5,4,3,2,1])) See Older Snippets! #### This Week's snippets: --- >will replace any spaces in file names with an underscore! ```bash for file in *; do mv "$file" `echo $file | tr ' ' '_'` ; done ## TAKING IT A STEP FURTHER: # Let's do it recursivley: function RecurseDirs () { oldIFS=$IFS IFS=$'\n' for f in "$@" do # YOUR CODE HERE! [] for file in *; do mv "$file" echo $file | tr ' ' '_' ; done if [[ -d "${f}" ]]; then cd "${f}" RecurseDirs $(ls -1 ".") cd .. fi done IFS=$oldIFS } RecurseDirs "./" --- ### Copy to clipboard jQuerry > Language: Javascript/Jquery >In combination with the script tag : <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> , this snippet will add a copy to clipboard button to all of your embedded <code> blocks. ```js $(document).ready(function() { $('code, pre').append('<span class="command-copy" ><i class="fa fa-clipboard" aria-hidden="true"></i></span>'); $('code span.command-copy').click(function(e) { var text = $(this).parent().text().trim(); //.text(); var copyHex = document.createElement('input'); copyHex.value = text document.body.appendChild(copyHex); copyHex.select(); document.execCommand('copy'); console.log(copyHex.value) document.body.removeChild(copyHex); }); $('pre span.command-copy').click(function(e) { var text = $(this).parent().text().trim(); var copyHex = document.createElement('input'); copyHex.value = text document.body.appendChild(copyHex); copyHex.select(); document.execCommand('copy'); console.log(copyHex.value) document.body.removeChild(copyHex); }); }) Append Files in PWD//APPEND-DIR.js const fs = require('fs'); let cat = require('child_process').execSync('cat *').toString('UTF-8'); fs.writeFile('output.md', cat, (err) => { if (err) throw err; }); doesUserFrequentStarbucks.js const isAppleDevice = /Mac|iPod|iPhone|iPad/.test(navigator.platform); console.log(isAppleDevice); // Result: will return true if user is on an Apple device arr-intersection.js/* function named intersection(firstArr) that takes in an array and returns a function. When the function returned by intersection is invoked passing in an array (secondArr) it returns a new array containing the elements common to both firstArr and secondArr. */ function intersection(firstArr) { return (secondArr) => { let common = []; for (let i = 0; i < firstArr.length; i++) { let el = firstArr[i]; if (secondArr.indexOf(el) > -1) { common.push(el); } } return common; }; } let abc = intersection(['a', 'b', 'c']); // returns a function console.log(abc(['b', 'd', 'c'])); // returns [ 'b', 'c' ] let fame = intersection(['f', 'a', 'm', 'e']); // returns a function console.log(fame(['a', 'f', 'z', 'b'])); // returns [ 'f', 'a' ] arr-of-cum-partial-sums.js/* First is recurSum(arr, start) which returns the sum of the elements of arr from the index start till the very end. Second is partrecurSum() that recursively concatenates the required sum into an array and when we reach the end of the array, it returns the concatenated array. */ //arr.length -1 = 5 // arr [ 1, 7, 12, 6, 5, 10 ] // ind [ 0 1 2 3 4 5 ] // ↟ ↟ // start end function recurSum(arr, start = 0, sum = 0) { if (start < arr.length) { return recurSum(arr, start + 1, sum + arr[start]); } return sum; } function rPartSumsArr(arr, partSum = [], start = 0, end = arr.length - 1) { if (start <= end) { return rPartSumsArr(arr, partSum.concat(recurSum(arr, start)), ++start, end); } return partSum.reverse(); } console.log('------------------------------------------------rPartSumArr------------------------------------------------'); console.log('rPartSumsArr(arr)=[ 1, 1, 5, 2, 6, 10 ]: ', rPartSumsArr(arr)); console.log('rPartSumsArr(arr1)=[ 1, 7, 12, 6, 5, 10 ]: ', rPartSumsArr(arr1)); console.log('------------------------------------------------rPartSumArr------------------------------------------------'); /* ------------------------------------------------rPartSumArr------------------------------------------------ rPartSumsArr(arr)=[ 1, 1, 5, 2, 6, 10 ]: [ 10, 16, 18, 23, 24, 25 ] rPartSumsArr(arr1)=[ 1, 7, 12, 6, 5, 10 ]: [ 10, 15, 21, 33, 40, 41 ] ------------------------------------------------rPartSumArr------------------------------------------------ */ camel2Kabab.js function camelToKebab(value) { return value.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); } camelCase.js function camel(str) { return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) { if (+match === 0) return ''; // or if (/\s+/.test(match)) for white spaces return index === 0 ? match.toLowerCase() : match.toUpperCase(); }); } concatLinkedLists.js function addTwoNumbers(l1, l2) { let result = new ListNode(0); let currentNode = result; let carryOver = 0; while (l1 != null || l2 != null) { let v1 = 0; let v2 = 0; if (l1 != null) v1 = l1.val; if (l2 != null) v2 = l2.val; let sum = v1 + v2 + carryOver; carryOver = Math.floor(sum / 10); sum = sum % 10; currentNode.next = new ListNode(sum); currentNode = currentNode.next; if (l1 != null) l1 = l1.next; if (l2 != null) l2 = l2.next; } if (carryOver > 0) { currentNode.next = new ListNode(carryOver); } return result.next; } fast-is-alpha-numeric.js//Function to test if a character is alpha numeric that is faster than a regular //expression in JavaScript let isAlphaNumeric = (char) => { char = char.toString(); let id = char.charCodeAt(0); if ( !(id > 47 && id < 58) && // if not numeric(0-9) !(id > 64 && id < 91) && // if not letter(A-Z) !(id > 96 && id < 123) // if not letter(a-z) ) { return false; } return true; }; console.log(isAlphaNumeric('A')); //true console.log(isAlphaNumeric(2)); //true console.log(isAlphaNumeric('z')); //true console.log(isAlphaNumeric(' ')); //false console.log(isAlphaNumeric('!')); //false find-n-replace.js function replaceWords(str, before, after) { if (/^[A-Z]/.test(before)) { after = after[0].toUpperCase() + after.substring(1); } else { after = after[0].toLowerCase() + after.substring(1); } return str.replace(before, after); } console.log(replaceWords('Let us go to the store', 'store', 'mall')); //"Let us go to the mall" console.log(replaceWords('He is Sleeping on the couch', 'Sleeping', 'sitting')); //"He is Sitting on the couch" console.log(replaceWords('His name is Tom', 'Tom', 'john')); //"His name is John" flatten-arr.js/*Simple Function to flatten an array into a single layer */ const flatten = (array) => array.reduce((accum, ele) => accum.concat(Array.isArray(ele) ? flatten(ele) : ele), []); isWeekDay.js const isWeekday = (date) => date.getDay() % 6 !== 0; console.log(isWeekday(new Date(2021, 0, 11))); // Result: true (Monday) console.log(isWeekday(new Date(2021, 0, 10))); // Result: false (Sunday) longest-common-prefix.js function longestCommonPrefix(strs) { let prefix = ''; if (strs.length === 0) return prefix; for (let i = 0; i < strs[0].length; i++) { const character = strs[0][i]; for (let j = 0; j < strs.length; j++) { if (strs[j][i] !== character) return prefix; } prefix = prefix + character; } return prefix; } ➤ Github Gists Github Gists list-of-my-websites Job Search Job Search Youtube Resume Engineering Portfolio
    https://bgoonz-blog.netlify.app/images/code.png
  • Platform Docs
    July 26, 2021 Webscraping w nodejs Web Scraping with Node.js So what's web scraping anyway? It involves automating away the laborious task of collecting information from websites. There are a lot of use cases for web scraping: you might want to collect prices from various e-commerce sites for a price comparison site. Or perhaps you need flight times and So what's web scraping anyway? It involves automating away the laborious task of collecting information from websites. There are a lot of use cases for web scraping: you might want to collect prices from various e-commerce sites for a price comparison site. Or perhaps you need flight times and hotel/AirBNB listings for a travel site. Maybe you want to collect emails from various directories for sales leads, or use data from the internet to train machine learning/AI models. Or you could even be wanting to build a search engine like Google! Getting started with web scraping is easy, and the process can be broken down into two main parts: acquiring the data using an HTML request library or a headless browser, and parsing the data to get the exact information you want. This guide will walk you through the process with the popular Node.js request-promise module, CheerioJS, and Puppeteer. Working through the examples in this guide, you will learn all the tips and tricks you need to become a pro at gathering any data you need with Node.js! We will be gathering a list of all the names and birthdays of U.S. presidents from Wikipedia and the titles of all the posts on the front page of Reddit. First things first: Let's install the libraries we'll be using in this guide (Puppeteer will take a while to install as it needs to download Chromium as well). Making your first request npm install --save request request-promise cheerio puppeteer Next, let's open a new text file (name the file potusScraper.js), and write a quick function to get the HTML of the Wikipedia “List of Presidents” page. const rp = require('request-promise'); const url = 'https://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States'; rp(url).then(function(html){//success! console.log(html);}).catch(function(err){//handle error}); Output:<!DOCTYPE html><html class="client-nojs" lang="en" dir="ltr"><head><meta charset="UTF-8"/><title>List of Presidents of the United States - Wikipedia</title>... Using Chrome DevTools Cool, we got the raw HTML from the web page! But now we need to make sense of this giant blob of text. To do that, we'll need to use Chrome DevTools to allow us to easily search through the HTML of a web page. Using Chrome DevTools is easy: simply open Google Chrome, and right click on the element you would like to scrape (in this case I am right clicking on George Washington, because we want to get links to all of the individual presidents' Wikipedia pages): Now, simply click inspect, and Chrome will bring up its DevTools pane, allowing you to easily inspect the page's source HTML. Parsing HTML with Cheerio.js Awesome, Chrome DevTools is now showing us the exact pattern we should be looking for in the code (a “big” tag with a hyperlink inside of it). Let's use Cheerio.js to parse the HTML we received earlier to return a list of links to the individual Wikipedia pages of U.S. presidents. const rp = require('request-promise'); const $ = require('cheerio'); const url = 'https://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States'; rp(url).then(function(html){//success! console.log($('big > a', html).length); console.log($('big > a', html));}).catch(function(err){//handle error}); Output: 45{ '0':{ type: 'tag', name: 'a', attribs: { href: '/wiki/George_Washington', title: 'George Washington' }, children: [ [Object] ], next: null, prev: null, parent:{ type: 'tag', name: 'big', attribs: {}, children: [Array], next: null, prev: null, parent: [Object] } },'1':{ type: 'tag'... We check to make sure there are exactly 45 elements returned (the number of U.S. presidents), meaning there aren't any extra hidden “big” tags elsewhere on the page. Now, we can go through and grab a list of links to all 45 presidential Wikipedia pages by getting them from the “attribs” section of each element. const rp = require('request-promise'); const $ = require('cheerio'); const url = 'https://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States'; rp(url).then(function(html){//success! const wikiUrls = []; for (let i = 0; i < 45; i++) { wikiUrls.push($('big > a', html)[i].attribs.href);} console.log(wikiUrls);}).catch(function(err){//handle error}); Output:['/wiki/George_Washington','/wiki/John_Adams','/wiki/Thomas_Jefferson','/wiki/James_Madison','/wiki/James_Monroe','/wiki/John_Quincy_Adams','/wiki/Andrew_Jackson',...] Now we have a list of all 45 presidential Wikipedia pages. Let's create a new file (named potusParse.js), which will contain a function to take a presidential Wikipedia page and return the president's name and birthday. First things first, let's get the raw HTML from George Washington's Wikipedia page. const rp = require('request-promise'); const url = 'https://en.wikipedia.org/wiki/George_Washington'; rp(url).then(function(html) { console.log(html);}).catch(function(err) {//handle error}); Output:<html class="client-nojs" lang="en" dir="ltr"><head><meta charset="UTF-8"/><title>George Washington - Wikipedia</title>... Let's once again use Chrome DevTools to find the syntax of the code we want to parse, so that we can extract the name and birthday with Cheerio.js. So we see that the name is in a class called “firstHeading” and the birthday is in a class called “bday”. Let's modify our code to use Cheerio.js to extract these two classes. const rp = require('request-promise'); const $ = require('cheerio'); const url = 'https://en.wikipedia.org/wiki/George_Washington'; rp(url).then(function(html) { console.log($('.firstHeading', html).text()); console.log($('.bday', html).text());}).catch(function(err) {//handle error}); Output: George Washington 1732-02-22 Putting it all together Perfect! Now let's wrap this up into a function and export it from this module. const rp = require('request-promise'); const $ = require('cheerio'); const potusParse = function(url) { return rp(url).then(function(html) { return { name: $('.firstHeading', html).text(), birthday: $('.bday', html).text(),};}).catch(function(err) {//handle error});}; module.exports = potusParse; Now let's return to our original file potusScraper.js and require the potusParse.js module. We'll then apply it to the list of wikiUrls we gathered earlier. const rp = require('request-promise'); const $ = require('cheerio'); const potusParse = require('./potusParse'); const url = 'https://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States'; rp(url).then(function(html) {//success! const wikiUrls = []; for (let i = 0; i < 45; i++) { wikiUrls.push($('big > a', html)[i].attribs.href);} return Promise.all( wikiUrls.map(function(url) { return potusParse('https://en.wikipedia.org' + url);}));}).then(function(presidents) { console.log(presidents);}).catch(function(err) {//handle error console.log(err);}); Output:[{ name: 'George Washington', birthday: '1732-02-22' },{ name: 'John Adams', birthday: '1735-10-30' },{ name: 'Thomas Jefferson', birthday: '1743-04-13' },{ name: 'James Madison', birthday: '1751-03-16' },{ name: 'James Monroe', birthday: '1758-04-28' },{ name: 'John Quincy Adams', birthday: '1767-07-11' },{ name: 'Andrew Jackson', birthday: '1767-03-15' },{ name: 'Martin Van Buren', birthday: '1782-12-05' },{ name: 'William Henry Harrison', birthday: '1773-02-09' },{ name: 'John Tyler', birthday: '1790-03-29' },{ name: 'James K. Polk', birthday: '1795-11-02' },{ name: 'Zachary Taylor', birthday: '1784-11-24' },{ name: 'Millard Fillmore', birthday: '1800-01-07' },{ name: 'Franklin Pierce', birthday: '1804-11-23' },{ name: 'James Buchanan', birthday: '1791-04-23' },{ name: 'Abraham Lincoln', birthday: '1809-02-12' },{ name: 'Andrew Johnson', birthday: '1808-12-29' },{ name: 'Ulysses S. Grant', birthday: '1822-04-27' },{ name: 'Rutherford B. Hayes', birthday: '1822-10-04' },{ name: 'James A. Garfield', birthday: '1831-11-19' },{ name: 'Chester A. Arthur', birthday: '1829-10-05' },{ name: 'Grover Cleveland', birthday: '1837-03-18' },{ name: 'Benjamin Harrison', birthday: '1833-08-20' },{ name: 'Grover Cleveland', birthday: '1837-03-18' },{ name: 'William McKinley', birthday: '1843-01-29' },{ name: 'Theodore Roosevelt', birthday: '1858-10-27' },{ name: 'William Howard Taft', birthday: '1857-09-15' },{ name: 'Woodrow Wilson', birthday: '1856-12-28' },{ name: 'Warren G. Harding', birthday: '1865-11-02' },{ name: 'Calvin Coolidge', birthday: '1872-07-04' },{ name: 'Herbert Hoover', birthday: '1874-08-10' },{ name: 'Franklin D. Roosevelt', birthday: '1882-01-30' },{ name: 'Harry S. Truman', birthday: '1884-05-08' },{ name: 'Dwight D. Eisenhower', birthday: '1890-10-14' },{ name: 'John F. Kennedy', birthday: '1917-05-29' },{ name: 'Lyndon B. Johnson', birthday: '1908-08-27' },{ name: 'Richard Nixon', birthday: '1913-01-09' },{ name: 'Gerald Ford', birthday: '1913-07-14' },{ name: 'Jimmy Carter', birthday: '1924-10-01' },{ name: 'Ronald Reagan', birthday: '1911-02-06' },{ name: 'George H. W. Bush', birthday: '1924-06-12' },{ name: 'Bill Clinton', birthday: '1946-08-19' },{ name: 'George W. Bush', birthday: '1946-07-06' },{ name: 'Barack Obama', birthday: '1961-08-04' },{ name: 'Donald Trump', birthday: '1946-06-14' }] Rendering JavaScript Pages Voilà! A list of the names and birthdays of all 45 U.S. presidents. Using just the request-promise module and Cheerio.js should allow you to scrape the vast majority of sites on the internet. Recently, however, many sites have begun using JavaScript to generate dynamic content on their websites. This causes a problem for request-promise and other similar HTTP request libraries (such as axios and fetch), because they only get the response from the initial request, but they cannot execute the JavaScript the way a web browser can. Thus, to scrape sites that require JavaScript execution, we need another solution. In our next example, we will get the titles for all of the posts on the front page of Reddit. Let's see what happens when we try to use request-promise as we did in the previous example. Output: const rp = require('request-promise'); const url = 'https://www.reddit.com'; rp(url).then(function(html){//success! console.log(html);}).catch(function(err){//handle error});} Here's what the output looks like:<!DOCTYPE html><html lang="en"><head><title>reddit: the front page of the internet</title>... Hmmm…not quite what we want. That's because getting the actual content requires you to run the JavaScript on the page! With Puppeteer, that's no problem. Puppeteer is an extremely popular new module brought to you by the Google Chrome team that allows you to control a headless browser. This is perfect for programmatically scraping pages that require JavaScript execution. Let's get the HTML from the front page of Reddit using Puppeteer instead of request-promise. const puppeteer = require('puppeteer'); const url = 'https://www.reddit.com'; puppeteer.launch().then(function(browser) { return browser.newPage();}).then(function(page) { return page.goto(url).then(function() { return page.content();});}).then(function(html) { console.log(html);}).catch(function(err) {//handle error}); Output:<!DOCTYPE html><html lang="en"><head><link href="//c.amazon-adsystem.com/aax2/apstag.js" rel="preload" as="script">... Nice! The page is filled with the correct content! Now we can use Chrome DevTools like we did in the previous example. It looks like Reddit is putting the titles inside “h2” tags. Let's use Cheerio.js to extract the h2 tags from the page. const puppeteer = require('puppeteer'); const $ = require('cheerio'); const url = 'https://www.reddit.com'; puppeteer.launch().then(function(browser) { return browser.newPage();}).then(function(page) { return page.goto(url).then(function() { return page.content();});}).then(function(html) {$('h2', html).each(function() { console.log($(this).text());});}).catch(function(err) {//handle error}); Output: Russian Pipeline. Upvote so that this is the first image people see when they Google “Russian Pipeline” John F. Kennedy Jr. Sitting in the pilot seat of the Marine One circa 1963 I didn't take it as a compliment. How beautiful is this Hustle like Faye The power of a salt water crocodile's tail. I'm 36, and will be dead inside of a year. F***ing genius. TIL Anthony Daniels, who endured years of discomfort in the C-3PO costume, was so annoyed by Alan Tudyk (Rogue One) playing K-2SO in the comfort of a motion-capture suit that he cursed at Tudyk. Tudyk later joked that a "fuck you" from Daniels was among the highest compliments he had ever received. Reminder about the fact UC Davis paid over $100k to remove this photo from the internet. King of the Hill reruns will start airing on Comedy Central July 24th[Image] Slow and steady White House: Trump open to Russia questioning US citizens Godzilla: King of the Monsters Teaser Banner He tried Soldier reunited with his dog after being away. Hiring a hitman on yourself and preparing for battle is the ultimate extreme sport. Two paintballs colliding midair My thoughts & prayers are with those ears When even your fantasy starts dropping hints Elon Musk's apology is out"When you're going private so you plant trees to throw some last shade at TDNW before you vanish." Thanos' farm advances. The soul children will have full bellies. 1024 points will give him the resources to double, and irrigate, his farm. (See comment) Some leaders prefer chess, others prefer hungry hippos. Travis Chapman, oil, 2018 The S.S. Ste. Claire, retired from ferrying amusement park goers, now ferries The Damned across the river Styx. A soldier is reunited with his dog*hits blunt* Today I Learned Black Panther Scene Representing the Pan-African Flag The precision of this hydraulic press. Let bring the game to another level When you're fighting a Dark Souls boss and you gamble to get 'just one extra hit' in instead of rolling out of range."I check for traps" Anon finds his home at last He's hungry Being a single mother is a thankless job. TIL That when you're pulling out Minigun, you're actually pulling out suitcase that then transforms into Minigun. OMG guys don't look!!! 🙈🙈🙈 hyubsama's emote of his own face denied for political reasons because twitch thinks its a picture of Kim Jong Un Additional Resources And there's the list! At this point you should feel comfortable writing your first web scraper to gather data from any website. Here are a few additional resources that you may find helpful during your web scraping journey: List of web scraping proxy services List of handy web scraping tools List of web scraping tips Comparison of web scraping proxies Cheerio Documentation Puppeteer Documentation
    https://bgoonz-blog.netlify.app/images/curious-europa.gif
  • Web-Dev-Hub
    Close Menu September 30, 2021 Web Development Tools In 2021 1. AI Chatbots Artificial Intelligence (AI) refers to the intelligence displayed by machines. It is primarily used to replace human intelligence. As the demand for AI-powered automation, communication, and analytics solutions will rise this year, more web developers will be focusing on building AI-based chatbots and virtual assistant apps. 2. Single Page Application Single-page applications, being light in weight, faster, and more efficient, increased both in demand and popularity in recent years. Developers will continue to use SPA for building responsive sites and apps in 2021. 3. JavaScript Frameworks JavaScript continues to remain one of the most preferred web development languages owing to its flexibility, power and evolving frameworks. This year too, we will see many new applications being developed in this developer-friendly language. 4. Progressive Web Apps (PWAs) These are special web applications which are designed to load with progressive enhancement. Because of its fast-loading and high functionality features, PWA will continue to remain one of the year's hottest web trends. 5. Mobile-Friendly Website Mobile-responsive sites are the ones that are designed to work smoothly across devices of all sizes. Owing to Google's mobile-first index and other search guidelines, developers will keep offering mobile-optimized sites this year and beyond. 6. Blockchain Technology Blockchain, which was founded as a technology for secure digital payments, is now finding its place as a distributed ledger, which is secure, decentralized and public and will dominate the web development industry in the coming years. 7. Motion UI Motion UI (User Interface) is a technology for creating visually appealing apps, especially animations, graphics, and transitions. Owing to its great ability for creating an interactive web design, Motion UI will be a primary tool for web developers in 2021. 8. Accelerated Mobile Pages (AMP) Accelerated mobile pages are an initiative by Google to ensure that existing desktop websites give an equally amazing user experience across mobile devices. Web developers who are familiar with this tech are helping companies to implement the same on their websites. 9. Cybersecurity Cybersecurity, which is another term for IT security, will continue to have its place in the online space as long as the world of internet is threatened by data breaches, hacking and similar cyber attacks. Developers with specialization in IT security will be in high demand this year. 10. VR and AR The Augmented Reality and Virtual Reality Technologies, which were introduced only two years back, have now become a core part of the modern web development frameworks. From digital reality to visualization to 3D replicas, AR/VR will be used for enhancing user experience in the online space. 11. Voice Search Following Google's increased focus on voice search queries, websites based on voice search optimization are now trending more than ever. As the number of people using voice searches will increase this year, so will the demand for websites optimized for the same. 12. Push Notification Push Notification is replacing the Newsletter service. It is not very old but maintaining a high conversion rate better than Newsletters. Services and platforms like Onesignal, ZoPush, Push Engage are improving day by day, so it will be in trend in upcoming years and web developers also have to take care of it. SAG IPL is a leading global web development company providing modern web/app development services to clients worldwide. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Python Practice
    June 03, 2021 Python Resources Beginners Guide To Python Basic Web Development Environment Setup Windows Subsystem for Linux (WSL) and Ubuntu levelup.gitconnected.com Put Python Anywhere on the Web Python in the browser. No installation required. trinket.io My favorite language for maintainability is Python. It has simple, clean syntax, object encapsulation, good library support, and optional named parameters. Bram Cohen Article on basic web development setup… it is geared towards web but VSCode is an incredibly versitile editor and this stack really could suit just about anyone working in the field of computer science. The Repository & Live Site Behind This Article: About Python(Taken From Tutorial Page Of Docs): Python enables programs to be written compactly and readably. Programs written in Python are typically much shorter than equivalent C, C++, or Java programs, for several reasons: the high-level data types allow you to express complex operations in a single statement; statement grouping is done by indentation instead of beginning and ending brackets; no variable or argument declarations are necessary. Installing Python: Windows To determine if your Windows computer already has Python 3: Open a command prompt by entering command prompt in the Windows 10 search box and selecting the Command Prompt App in the Best match section of the results. Enter the following command and then select the Enter key: ConsoleCopy python --version Running python --version may not return a value, or may return an error message stating 'python' is not recognized as an internal or external command, operable program or batch file. This indicates Python is not installed on your Windows system. If you see the word Python with a set of numbers separated by . characters, some version of Python is installed. i.e. Python 3.8.0 As long as the first number is 3, you have Python 3 installed. Download Page: https://www.python.org/downloads/release/python-395/ Download Link: https://www.python.org/ftp/python/3.9.5/python-3.9.5-amd64.exe Install Jupyter Notebooks: pip If you use pip, you can install it with: If installing using pip install --user, you must add the user-level bin directory to your PATH environment variable in order to launch jupyter lab. If you are using a Unix derivative (FreeBSD, GNU / Linux, OS X), you can achieve this by using export PATH="$HOME/.local/bin:$PATH" command. pipenv If you use pipenv, you can install it as: or from a git checkout: When using pipenv, in order to launch jupyter lab, you must activate the project's virtualenv. For example, in the directory where pipenv's Pipfile and Pipfile.lock live (i.e., where you ran the above commands): Alternatively, you can run jupyter lab inside the virtualenv with Jupyter Notebook Viewer Python Syntax Python syntax was made for readability, and easy editing. For example, the python language uses a : and indented code, while javascript and others generally use {} and indented code. First Program Lets create a python 3 repl, and call it Hello World. Now you have a blank file called main.py. Now let us write our first line of code: Brian Kernighan actually wrote the first “Hello, World!” program as part of the documentation for the BCPL programming language developed by Martin Richards. Now, press the run button, which obviously runs the code. If you are not using replit, this will not work. You should research how to run a file with your text editor. Command Line If you look to your left at the console where hello world was just printed, you can see a >, >>>, or $ depending on what you are using. After the prompt, try typing a line of code. The command line allows you to execute single lines of code at a time. It is often used when trying out a new function or method in the language. New: Comments! Another cool thing that you can generally do with all languages, are comments. In python, a comment starts with a #. The computer ignores all text starting after the #.# Write some comments! If you have a huge comment, do not comment all the 350 lines, just put ''' before it, and ''' at the end. Technically, this is not a comment but a string, but the computer still ignores it, so we will use it. New: Variables! Unlike many other languages, there is no var, let, or const to declare a variable in python. You simply go name = 'value'. Remember, there is a difference between integers and strings. Remember: String = "". To convert between these two, you can put an int in a str() function, and a string in a int() function. There is also a less used one, called a float. Mainly, these are integers with decimals. Change them using the float() command. https://repl.it/@bgoonz/second-scr?lite=true&referrer=https%3A%2F%2Fbryanguner.medium.com Instead of using the , in the print function, you can put a + to combine the variables and string. Operators There are many operators in python:+-/* These operators are the same in most languages, and allow for addition, subtraction, division, and multiplicaiton. Now, we can look at a few more complicated ones: simpleops.py You should already know everything shown above, as it is similar to other languages. If you continue down, you will see more complicated ones. complexop.py The ones above are to edit the current value of the variable. Sorry to JS users, as there is no i++; or anything. Fun Fact: The python language was named after Monty Python. If you really want to know about the others, view Py Operators More Things With Strings Like the title? Anyways, a ' and a " both indicate a string, but do not combine them! quotes.py slicing.py String Slicing You can look at only certain parts of the string by slicing it, using [num:num]. The first number stands for how far in you go from the front, and the second stands for how far in you go from the back. Methods and Functions Here is a list of functions/methods we will go over:.strip() len().lower().upper().replace().split() New: Input() Input is a function that gathers input entered from the user in the command line. It takes one optional parameter, which is the users prompt. inp.py If you wanted to make it smaller, and look neater to the user, you could do… inp2.py Running: inp.py inp2.py New: Importing Modules Python has created a lot of functions that are located in other .py files. You need to import these modules to gain access to the,, You may wonder why python did this. The purpose of separate modules is to make python faster. Instead of storing millions and millions of functions, , it only needs a few basic ones. To import a module, you must write input <modulename>. Do not add the .py extension to the file name. In this example , we will be using a python created module named random. module.py Now, I have access to all functions in the random.py file. To access a specific function in the module, you would do <module>.<function>. For example: module2.py*Pro Tip: Do from random import randint to not have to do random.randint(), just randint() To import all functions from a module, you could do from random import ** New: Loops! Loops allow you to repeat code over and over again. This is useful if you want to print Hi with a delay of one second 100 times. for Loop The for loop goes through a list of variables, making a seperate variable equal one of the list every time. Let's say we wanted to create the example above. loop.py This will print Hello with a .3 second delay 100 times. This is just one way to use it, but it is usually used like this: loop2.py https://storage.googleapis.com/replit/images/1539649280875_37d22e6d49e8e8fbc453631def345387.pn while Loop The while loop runs the code while something stays true. You would put while <expression>. Every time the loop runs, it evaluates if the expression is True. It it is, it runs the code, if not it continues outside of the loop. For example: while.py Or you could do: while2.py New: if Statement The if statement allows you to check if something is True. If so, it runs the code, if not, it continues on. It is kind of like a while loop, but it executes only once. An if statement is written: if.py Now, you may think that it would be better if you could make it print only one message. Not as many that are True. You can do that with an elif statement: elif.py Now, you may wonder how to run code if none work. Well, there is a simple statement called else: else.py New: Functions (def) So far, you have only seen how to use functions other people have made. Let use the example that you want to print the a random number between 1 and 9, and print different text every time. It is quite tiring to type: Characters: 389 nofunc.py Now with functions, you can seriously lower the amount of characters: Characters: 254 functions.py Project Based Learning: The following is a modified version of a tutorial posted By: InvisibleOne I would cite the original tutorial it's self but at the time of this writing I can no longer find it on his repl.it profile and so the only reference I have are my own notes from following the tutorial when I first found it. 1. Adventure Story The first thing you need with an adventure story is a great storyline, something that is exciting and fun. The idea is, that at each pivotal point in the story, you give the player the opportunity to make a choice. First things first, let's import the stuff that we need, like this: Now, we need some variables to hold some of the player data. Ok, now we have the player's name and nickname, let's welcome them to the game Now for the story. The most important part of all stories is the introduction, so let's print our introduction Now, we'll give the player their first choice There you have it, a pretty simple choose your own ending story. You can make it as complex or uncomplex as you like. 2. TEXT ENCODER Ever make secret messages as a kid? I used to. Anyways, here's the way you can make a program to encode messages! It's pretty simple. First things first, let's get the message the user wants to encode, we'll use input() for that: Now we need to split that string into a list of characters, this part is a bit more complicated. Now we need to convert the characters into code, well do this with a for loop: Once we've encoded the text, we'll print it back for the user And if you want to decode something, it is this same process but in reverse! 3. Guess my Number Number guessing games are fun and pretty simple, all you need are a few loops. To start, we need to import random. That is pretty simple. Now we'll make a list with the numbers were want available for the game Next, we get a random number from the list Now, we need to ask the user for input, we'll to this with a while loop Have fun with this! 4. Notes Here is a more advanced project, but still pretty easy. This will be using a txt file to save some notes. The first thing we need to do is to create a txt file in your repl, name it 'notes.txt' Now, to open a file in python we use open('filename', type) The type can be 'r' for read, or 'w' for write. There is another option, but we won't be using that here. Now, the first thing we are going to do is get what the user would like to save: Now we'll open our file and save that text There we go, now the information is in the file. Next, we'll retrieve it There we go, that's how you can open files and close files with python 5. Random Dare Generator Who doesn't love a good dare? Here is a program that can generate random dares. The first thing we'll need to do is as always, import random. Then we'll make some lists of dares
    https://bgoonz-blog.netlify.app/images/2.jpg
  • python
    June 03, 2021 Python Resources Python Study Guide for a JavaScript Programmer []( https://github.com/bgoonz) Applications of Tutorial & Cheat Sheet Respectivley (At Bottom Of Tutorial): Basics PEP8 : Python Enhancement Proposals, style-guide for Python. print is the equivalent of console.log.'print() == console.log()'# is used to make comments in your code. Python has a built in help function that let's you see a description of the source code without having to navigate to it… “-SickNasty … Autor Unknown” Numbers Python has three types of numbers: Integer Positive and Negative Counting Numbers. No Decimal Point Created by a literal non-decimal point number … or … with the int() constructor. 3. Complex Numbers Consist of a real part and imaginary part. Boolean is a subtype of integer in Python.🤷‍♂️ If you came from a background in JavaScript and learned to accept the premise(s) of the following meme… Than I am sure you will find the means to suspend your disbelief. KEEP IN MIND: The i is switched to a j in programming. T*his is because the letter i is common place as the de facto index for any and all enumerable entities so it just makes sense not to compete for name-**space * when there's another 25 letters that don't get used for every loop under the sun. My most medium apologies to Leonhard Euler. Type Casting : The process of converting one number to another. The arithmetic operators are the same between JS and Python, with two additions:“**” : Double asterisk for exponent.“//” : Integer Division. There are no spaces between math operations in Python. Integer Division gives the other part of the number from Module; it is a way to do round down numbers replacing Math.floor() in JS. There are no ++ and -- in Python, the only shorthand operators are: Strings Python uses both single and double quotes. You can escape strings like so 'Jodi asked, "What\'s up, Sam?"' Multiline strings use triple quotes. Use the len() function to get the length of a string. Python uses zero-based indexing Python allows negative indexing (thank god!) Python let's you use ranges You can think of this as roughly equivalent to the slice method called on a JavaScript object or string… *(mind you that in JS … strings are wrapped in an object (under the hood)… upon which the string methods are actually called. As a immutable privative type by textbook definition, a string literal could not hope to invoke most of it's methods without violating the state it was bound to on initialization if it were not for this bit of syntactic sugar.)* The end range is exclusive just like slice in JS. The index string function is the equiv. of indexOf() in JS The count function finds out how many times a substring appears in a string… pretty nifty for a hard coded feature of the language. You can use + to concatenate strings, just like in JS. You can also use “*” to repeat strings or multiply strings. Use the format() function to use placeholders in a string to input values later on.*Shorthand way to use format function is: *print(f'Your name is {first name} {last name}') Some useful string methods. Note that in JS join is used on an Array, in Python it is used on String. There are also many handy testing methods. Variables and Expressions Duck-Typing : Programming Style which avoids checking an object's type to figure out what it can do. Duck Typing is the fundamental approach of Python. Assignment of a value automatically declares a variable. You can chain variable assignments to give multiple var names the same value. Use with caution as this is highly unreadable The value and type of a variable can be re-assigned at any time.*NaN does not exist in Python, but you can 'create' it like so: print(float("nan"))* Python replaces null with none.*none is an object and can be directly assigned to a variable.* Using none is a convenient way to check to see why an action may not be operating correctly in your program. Boolean Data Type One of the biggest benefits of Python is that it reads more like English than JS does. By default, Python considers an object to be true UNLESS it is one of the following: Constant None or False Zero of any numeric type. Empty Sequence or Collection. True and False must be capitalized Comparison Operators Python uses all the same equality operators as JS. In Python, equality operators are processed from left to right. Logical operators are processed in this order: NOT AND OR Just like in JS, you can use parentheses to change the inherent order of operations. Short Circuit : Stopping a program when a true or false has been reached. Identity vs Equality In the Python community it is better to use is and is not over == or != If Statements Remember the order of elif statements matter. While Statements Break statement also exists in Python. As are continue statements Try/Except Statements Python equivalent to try/catch You can name an error to give the output more specificity. You can also use the pass commmand to by pass a certain error. The pass method won't allow you to bypass every single error so you can chain an exception series like so: You can use an else statement to end a chain of except statements. finally is used at the end to clean up all actions under any circumstance. Using duck typing to check to see if some value is able to use a certain method. Pass Pass Keyword is required to write the JS equivalent of : Functions Function definition includes: The def keyword The name of the function A list of parameters enclosed in parentheses. A colon at the end of the line. One tab indentation for the code to run. You can use default parameters just like in JS Keep in mind, default parameters must always come after regular parameters. You can specify arguments by name without destructuring in Python. The lambda keyword is used to create anonymous functions and are supposed to be one-liners. toUpper = lambda s: s.upper() Notes Formatted Strings Remember that in Python join() is called on a string with an array/list passed in as the argument. Python has a very powerful formatting engine. format() is also applied directly to strings. Comma Thousands Separator Date and Time Percentage Data Tables Python can be used to display html, css, and JS. It is common to use Python as an API (Application Programming Interface) Structured Data Sequence : The most basic data structure in Python where the index determines the order. List Tuple Range Collections : Unordered data structures, hashable values. Dictionaries Sets Iterable : Generic name for a sequence or collection; any object that can be iterated through. Can be mutable or immutable. Built In Data Types Lists are the python equivalent of arrays. You can instantiate Test if a value is in a list. Instantiated with parentheses Sometimes instantiated without Tuple() built in can be used to convert other data into a tuple Ranges : A list of numbers which can't be changed; often used with for loops. Declared using one to three parameters. Start : opt. default 0, first # in sequence. Stop : required next number past the last number in the sequence. Step : opt. default 1, difference between each number in the sequence. Dictionaries : Mappable collection where a hashable value is used as a key to ref. an object stored in the dictionary. Mutable. Declared with curly braces of the built in dict() Benefit of dictionaries in Python is that it doesn't matter how it is defined, if the keys and values are the same the dictionaries are considered equal. Use the in operator to see if a key exists in a dictionary. S ets : Unordered collection of distinct objects; objects that need to be hashable. Always be unique, duplicate items are auto dropped from the set. Common Uses: Removing Duplicates Membership Testing Mathematical Operators: Intersection, Union, Difference, Symmetric Difference. Standard Set is mutable, Python has a immutable version called frozenset. Sets created by putting comma seperated values inside braces: Also can use set constructor to automatically put it into a set. filter(function, iterable) : creates new iterable of the same type which includes each item for which the function returns true. map(function, iterable) : creates new iterable of the same type which includes the result of calling the function on every item of the iterable. sorted(iterable, key=None, reverse=False) : creates a new sorted list from the items in the iterable. Output is always a list key: opt function which coverts and item to a value to be compared. reverse: optional boolean. enumerate(iterable, start=0) : starts with a sequence and converts it to a series of tuples(0, 'First'), (1, 'Second'), (2, 'Third'), (3, 'Fourth')(1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth') zip(*iterables) : creates a zip object filled with tuples that combine 1 to 1 the items in each provided iterable. Functions that analyze iterable len(iterable) : returns the count of the number of items. max(*args, key=None) : returns the largest of two or more arguments. max(iterable, key=None) : returns the largest item in the iterable. key optional function which converts an item to a value to be compared. min works the same way as max sum(iterable) : used with a list of numbers to generate the total. There is a faster way to concatenate an array of strings into one string, so do not use sum for that. any(iterable) : returns True if any items in the iterable are true. all(iterable) : returns True is all items in the iterable are true. Working with dictionaries dir(dictionary) : returns the list of keys in the dictionary. Working with sets Union : The pipe | operator or union(*sets) function can be used to produce a new set which is a combination of all elements in the provided set. Intersection : The & operator ca be used to produce a new set of only the elements that appear in all sets. Symmetric Difference : The ^ operator can be used to produce a new set of only the elements that appear in exactly one set and not in both. For Statements In python, there is only one for loop. Always Includes: 1. The for keyword 2. A variable name 3. The 'in' keyword 4. An iterable of some kid 5. A colon 6. On the next line, an indented block of code called the for clause. You can use break and continue statements inside for loops as well. You can use the range function as the iterable for the for loop. Common technique is to use the len() on a pre-defined list with a for loop to iterate over the indices of the list. You can loop and destructure at the same time. Prints 1, 2 Prints 3, 4 Prints 5, 6 You can use values() and keys() to loop over dictionaries. Prints red Prints 42 Prints color Prints age For loops can also iterate over both keys and values. Getting tuples Prints ('color', 'red') Prints ('age', 42) Destructuring to values Prints Key: age Value: 42 Prints Key: color Value: red Looping over string When you order arguments within a function or function call, the args need to occur in a particular order: formal positional args.*args keyword args with default values**kwargs Importing in Python Modules are similar to packages in Node.js Come in different types: Built-In, Third-Party, Custom. All loaded using import statements. Terms module : Python code in a separate file. package : Path to a directory that contains modules. init.py : Default file for a package. submodule : Another file in a module's folder. function : Function in a module. A module can be any file but it is usually created by placing a special file init.py into a folder. pic Try to avoid importing with wildcards in Python. Use multiple lines for clarity when importing. Watching Out for Python 2 Python 3 removed <> and only uses != format() was introduced with P3 All strings in P3 are unicode and encoded. md5 was removed. ConfigParser was renamed to configparser sets were killed in favor of set() class. print was a statement in P2, but is a function in P3. Topics revisited (in python syntax) Cheat Sheet: If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub Or Checkout my personal Resource Site: Python Cheat Sheet: If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content:
    https://bgoonz-blog.netlify.app/images/python.png
  • Platform Docs
    May 23, 2021 Netlify CMS Intro Add to Your Site | Netlify CMS Open source content management for your Git workflow You can adapt Netlify CMS to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on GitHub, GitLab, or Bitbucket. You can also create your own custom backend. This tutorial guides you through the steps for adding Netlify CMS to a site that's built with a common static site generator, like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can start from a template or dive right into configuration options. App File Structure A static admin folder contains all Netlify CMS files, stored at the root of your published site. Where you store this folder in the source files depends on your static site generator. Here's the static file location for a few of the most popular static site generators: These generators store static files in Jekyll, GitBook/ (project root) Hugo, Gatsby, Nuxt, Gridsome, Zola, Sapper/static Next/public Hexo, Middleman, Jigsaw/source Spike/views Wyam/input Pelican/content VuePress/.vuepress/public Elmstatic/_site 11ty/_site preact-cli/src/static If your generator isn't listed here, you can check its documentation, or as a shortcut, look in your project for a css or images folder. The contents of folders like that are usually processed as static files, so it's likely you can store your admin folder next to those. (When you've found the location, feel free to add it to these docs by filing a pull request!) Inside the admin folder, you'll create two files: admin ├ index.html └ config.yml The first file, admin/index.html, is the entry point for the Netlify CMS admin interface. This means that users navigate to yoursite.com/admin/ to access it. On the code side, it's a basic HTML starter page that loads the Netlify CMS JavaScript file. In this example, we pull the file from a public CDN:<!doctype html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Content Manager</title> </head> <body> <script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> </body> </html> In the code above the script is loaded from the unpkg CDN. Should there be any issue, jsDelivr can be used as an alternative source. Simply set the src to https://cdn.jsdelivr.net/npm/netlify-cms@^2.0.0/dist/netlify-cms.js The second file, admin/config.yml, is the heart of your Netlify CMS installation, and a bit more complex. The Configuration section covers the details. Installing with npm You can also use Netlify CMS as an npm module. Wherever you import Netlify CMS, it automatically runs, taking over the current page. Make sure the script that imports it only runs on your CMS page. First install the package and save it to your project: npm install netlify-cms-app --save Then import it (assuming your project has tooling for imports): import CMS from 'netlify-cms-app' CMS.init() CMS.registerPreviewTemplate('my-template', MyTemplate) Configuration Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your admin/config.yml file. Backend We're using Netlify for our hosting and authentication in this tutorial, so backend configuration is fairly straightforward. For GitHub and GitLab repositories, you can start your Netlify CMS config.yml file with these lines: backend: name: git-gateway branch: master (For Bitbucket repositories, use the Bitbucket backend instructions instead.) The configuration above specifies your backend protocol and your publication branch. Git Gateway is an open source API that acts as a proxy between authenticated users of your site and your site repo. (We'll get to the details of that in the Authentication section below.) If you leave out the branch declaration, it defaults to master. Editorial Workflow Note: Editorial workflow works with GitHub repositories, and support for GitLab and Bitbucket is in beta. By default, saving a post in the CMS interface pushes a commit directly to the publication branch specified in backend. However, you also have the option to enable the Editorial Workflow, which adds an interface for drafting, reviewing, and approving posts. To do this, add the following line to your Netlify CMS config.yml: publish_mode: editorial_workflow Media and Public Folders Netlify CMS allows users to upload images directly within the editor. For this to work, the CMS needs to know where to save them. If you already have an images folder in your project, you could use its path, possibly creating an uploads sub-folder, for example: media_folder: "images/uploads" If you're creating a new folder for uploaded media, you'll need to know where your static site generator expects static files. You can refer to the paths outlined above in App File Structure, and put your media folder in the same location where you put the admin folder. Note that the media_folder file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site: media_folder: "static/images/uploads" public_folder: "/images/uploads" The configuration above adds a new setting, public_folder. While media_folder specifies where uploaded files are saved in the repo, public_folder indicates where they are found in the published site. Image src attributes use this path, which is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening /. If `public folder is not set, Netlify CMS defaults to the same value as media folder, adding an opening/` if one is not included. Collections Collections define the structure for the different content types on your static site. Since every site is different, the collections settings differ greatly from one site to the next. Let's say your site has a blog, with the posts stored in _posts/blog, and files saved in a date-title format, like 1999-12-31-lets-party.md. Each post begins with settings in yaml-formatted front matter, like so:--- layout: blog title: "Let's Party" date: 1999-12-31 11:59:59 -0800 thumbnail: "/images/prince.jpg" rating: 5 --- This is the post body, where I write about our last chance to party before the Y2K bug destroys us all. Given this example, our collections settings would look like this in your NetlifyCMS config.yml file: collections: - name: "blog" label: "Blog" folder: "_posts/blog" create: true slug: "{{year}}-{{month}}-{{day}}-{{slug}}" fields: - {label: "Layout", name: "layout", widget: "hidden", default: "blog"} - {label: "Title", name: "title", widget: "string"} - {label: "Publish Date", name: "date", widget: "datetime"} - {label: "Featured Image", name: "thumbnail", widget: "image"} - {label: "Rating (scale of 1-5)", name: "rating", widget: "number"} - {label: "Body", name: "body", widget: "markdown"} Let's break that down: name Post type identifier, used in routes. Must be unique. label What the admin UI calls the post type. folder Where files of this type are stored, relative to the repo root. create Set to true to allow users to create new files in this collection. slug Template for filenames. {{year}}, {{month}}, and {{day}} pulls from the post's date field or save date. {{slug}} is a url-safe version of the post's title. Default is simply {{slug}}. fields Fields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for body, which follows the front matter). Each field contains the following properties: label: Field label in the editor UI. name: Field name in the document front matter. widget: Determines UI style and value data type (details below). default (optional): Sets a default value for the field. As described above, the widget property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the name specified for that field. A full listing of available widgets can be found in the Widgets doc. Based on this example, you can go through the post types in your site and add the appropriate settings to your Netlify CMS config.yml file. Each post type should be listed as a separate node under the collections field. See the Collections reference doc for more configuration options. Filter The entries for any collection can be filtered based on the value of a single field. The example collection below only shows post entries with the value en in the language field. collections: - name: "posts" label: "Post" folder: "_posts" filter: field: language value: en fields: - {label: "Language", name: "language"} Authentication Now that you have your Netlify CMS files in place and configured, all that's left is to enable authentication. We're using the Netlify platform here because it's one of the quickest ways to get started, but you can learn about other authentication options in the Backends doc. Setup on Netlify Netlify offers a built-in authentication service called Identity. In order to use it, connect your site repo with Netlify. Netlify has published a general Step-by-Step Guide for this, along with detailed guides for many popular static site generators, including Jekyll, Hugo, Hexo, Middleman, Gatsby, and more. Enable Identity and Git Gateway Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: Go to Settings > Identity, and select Enable Identity service. Under Registration preferences, select Open or Invite only. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under External providers. Scroll down to Services > Git Gateway, and click Enable Git Gateway. This authenticates with your Git host and generates an API access token. In this case, we're leaving the Roles field blank, which means any logged in user may access the CMS. For information on changing this, check the Netlify Identity documentation. Add the Netlify Identity Widget With the backend set to handle authentication, now you need a frontend interface to connect to it. The open source Netlify Identity Widget is a drop-in widget made for just this purpose. To include the widget in your site, add the following script tag in two places:<script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script> Add this to the <head> of your CMS index page at /admin/index.html, as well as the <head> of your site's main index page. Depending on how your site generator is set up, this may mean you need to add it to the default template, or to a "partial" or "include" template. If you can find where the site stylesheet is linked, that's probably the right place. Alternatively, you can include the script in your site using Netlify's Script Injection feature. When a user logs in with the Netlify Identity widget, an access token directs to the site homepage. In order to complete the login and get back to the CMS, redirect the user back to the /admin/ path. To do this, add the following script before the closing body tag of your site's main index page:<script> if (window.netlifyIdentity) { window.netlifyIdentity.on("init", user => { if (!user) { window.netlifyIdentity.on("login", () => { document.location.href = "/admin/"; }); } }); } </script> Note: This example script requires modern JavaScript and does not work on IE11. For legacy browser support, use function expressions ( function () {}) in place of the arrow functions (() => {}), or use a transpiler such as Babel. Accessing the CMS Your site CMS is now fully configured and ready for login! If you set your registration preference to "Invite only," invite yourself (and anyone else you choose) as a site user. To do this, select the Identity tab from your site dashboard, and then select the Invite users button. Invited users receive an email invitation with a confirmation link. Clicking the link will take you to your site with a login prompt. If you left your site registration open, or for return visits after confirming an email invitation, access your site's CMS at yoursite.com/admin/. Note: No matter where you access Netlify CMS — whether running locally, in a staging environment, or in your published site — it always fetches and commits files in your hosted repository (for example, on GitHub), on the branch you configured in your Netlify CMS config.yml file. This means that content fetched in the admin UI matches the content in the repository, which may be different from your locally running site. It also means that content saved using the admin UI saves directly to the hosted repository, even if you're running the UI locally or in staging. Happy posting! Source
    https://bgoonz-blog.netlify.app/images/curious-europa.gif
  • Intro to Netlify CMS
    September 30, 2021 Netlify CMS Reference Sheet lorem-ipsum Overview Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflows. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git. At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub, GitLab, or Bitbucket API. This provides many advantages, including: Fast, web-based UI: With rich-text editing, real-time preview, and drag-and-drop media uploads. Platform agnostic: Works with most static site generators. Easy installation: Add two files to your site and hook up the backend by including those files in your build process or linking to our Content Delivery Network (CDN). Modern authentication: Using GitHub, GitLab, or Bitbucket and JSON web tokens. Flexible content types: Specify an unlimited number of content types with custom fields. Fully extensible: Create custom-styled previews, UI widgets, and editor plugins. Netlify CMS vs. Netlify Netlify.com is a platform you can use to automatically build, deploy, serve, and manage your frontend sites and web apps. It also provides a variety of other features like form processing, serverless functions, and split testing. Not all Netlify sites use Netlify CMS, and not all sites using Netlify CMS are on Netlify. The folks at Netlify created Netlify CMS to fill a gap in the static site generation pipeline. There were some great proprietary headless CMS options, but no real contenders that were open source and extensible—that could turn into a community-built ecosystem like WordPress or Drupal. For that reason, Netlify CMS is made to be community-driven, and has never been locked to the Netlify platform (despite the name). With this in mind, you can: Use Netlify CMS without Netlify and deploy your site where you always have, hooking up your own CI, site hosting, CDN, etc. Use Netlify without Netlify CMS and edit your static site in your code editor. Or, use them together and have a fully-working CMS-enabled site with one click! If you hook up Netlify CMS to your website, you're basically adding a tool for content editors to make commits to your site repository without touching code or learning Git. Add to Your Site These generatorsstore static files in Jekyll, GitBook/ (project root)Hugo, Gatsby, Nuxt, Gridsome, Zola, Sapper/staticNext/publicHexo, Middleman, Jigsaw/sourceSpike/viewsWyam/inputPelican/contentVuePress/.vuepress/publicElmstatic/_site11ty/_sitepreact-cli/src/staticnamePost type identifier, used in routes. Must be unique.labelWhat the admin UI calls the post type.folderWhere files of this type are stored, relative to the repo root.createSet to true to allow users to create new files in this collection.slugTemplate for filenames. {{year}}, {{month}}, and {{day}} pulls from the post's date field or save date. {{slug}} is a url-safe version of the post's title. Default is simply {{slug}}.fieldsFields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for body, which follows the front matter). Each field contains the following properties: You can adapt Netlify CMS to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on GitHub, GitLab, or Bitbucket. You can also create your own custom backend. This tutorial guides you through the steps for adding Netlify CMS to a site that's built with a common static site generator, like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can start from a template or dive right into configuration options. App File Structure A static admin folder contains all Netlify CMS files, stored at the root of your published site. Where you store this folder in the source files depends on your static site generator. Here's the static file location for a few of the most popular static site generators: If your generator isn't listed here, you can check its documentation, or as a shortcut, look in your project for a css or images folder. The contents of folders like that are usually processed as static files, so it's likely you can store your admin folder next to those. (When you've found the location, feel free to add it to these docs by filing a pull request!) Inside the admin folder, you'll create two files: The first file, admin/index.html, is the entry point for the Netlify CMS admin interface. This means that users navigate to yoursite.com/admin/ to access it. On the code side, it's a basic HTML starter page that loads the Netlify CMS JavaScript file. The second file, admin/config.yml, is the heart of your Netlify CMS installation, and a bit more complex. The Configuration section covers the details. In this example, we pull the admin/index.html file from a public CDN. In the code above the script is loaded from the unpkg CDN. Should there be any issue, jsDelivr can be used as an alternative source. Simply set the src to https://cdn.jsdelivr.net/npm/netlify-cms@^2.0.0/dist/netlify-cms.js Installing with npm You can also use Netlify CMS as an npm module. Wherever you import Netlify CMS, it automatically runs, taking over the current page. Make sure the script that imports it only runs on your CMS page. First install the package and save it to your project: Then import it (assuming your project has tooling for imports): Configuration Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your admin/config.yml file. Backend We're using Netlify for our hosting and authentication in this tutorial, so backend configuration is fairly straightforward. For GitHub and GitLab repositories, you can start your Netlify CMS config.yml file with these lines:(For Bitbucket repositories, use the _[ Bitbucket backend]( https://www.netlifycms.org/docs/bitbucket-backend) instructions instead.)_ The configuration above specifies your backend protocol and your publication branch. Git Gateway is an open source API that acts as a proxy between authenticated users of your site and your site repo. (We'll get to the details of that in the Authentication section below.) If you leave out the branch declaration, it defaults to master. Editorial Workflow Note: Editorial workflow works with GitHub repositories, and support for GitLab and Bitbucket is in beta. By default, saving a post in the CMS interface pushes a commit directly to the publication branch specified in backend. However, you also have the option to enable the Editorial Workflow, which adds an interface for drafting, reviewing, and approving posts. To do this, add the following line to your Netlify CMS config.yml: Media and Public Folders Netlify CMS allows users to upload images directly within the editor. For this to work, the CMS needs to know where to save them. If you already have an images folder in your project, you could use its path, possibly creating an uploads sub-folder, for example: If you're creating a new folder for uploaded media, you'll need to know where your static site generator expects static files. You can refer to the paths outlined above in App File Structure, and put your media folder in the same location where you put the admin folder. Note that themedia_folder file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site: The configuration above adds a new setting, public folder. While media folder specifies where uploaded files are saved in the repo, public_folder indicates where they are found in the published site. Image src attributes use this path, which is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening /. If public folder is not set, Netlify CMS defaults to the same value as media folder, adding an opening / if one is not included. Collections Collections define the structure for the different content types on your static site. Since every site is different, the collections settings differ greatly from one site to the next. Let's say your site has a blog, with the posts stored in _posts/blog, and files saved in a date-title format, like 1999-12-31-lets-party.md. Each post begins with settings in yaml-formatted front matter, like so: Given this example, our collections settings would look like this in your NetlifyCMS config.yml file: Let's break that down: label: Field label in the editor UI. name: Field name in the document front matter. widget: Determines UI style and value data type (details below). default (optional): Sets a default value for the field. As described above, the widget property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the name specified for that field. A full listing of available widgets can be found in the Widgets doc. Based on this example, you can go through the post types in your site and add the appropriate settings to your Netlify CMS config.yml file. Each post type should be listed as a separate node under the collections field. See the Collections reference doc for more configuration options. Filter The entries for any collection can be filtered based on the value of a single field. The example collection below only shows post entries with the value en in the language field. Authentication Now that you have your Netlify CMS files in place and configured, all that's left is to enable authentication. We're using the Netlify platform here because it's one of the quickest ways to get started, but you can learn about other authentication options in the Backends doc. Setup on Netlify Netlify offers a built-in authentication service called Identity. In order to use it, connect your site repo with Netlify. Netlify has published a general Step-by-Step Guide for this, along with detailed guides for many popular static site generators, including Jekyll, Hugo, Hexo, Middleman, Gatsby, and more. Enable Identity and Git Gateway Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: Go to Settings > Identity, and select Enable Identity service. Under Registration preferences, select Open or Invite only. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under External providers. Scroll down to Services > Git Gateway, and click Enable Git Gateway. This authenticates with your Git host and generates an API access token. In this case, we're leaving the Roles field blank, which means any logged in user may access the CMS. For information on changing this, check the Netlify Identity documentation. Add the Netlify Identity Widget With the backend set to handle authentication, now you need a frontend interface to connect to it. The open source Netlify Identity Widget is a drop-in widget made for just this purpose. To include the widget in your site, add the following script tag in two places: Add this to the <head> of your CMS index page at /admin/index.html, as well as the <head> of your site's main index page. Depending on how your site generator is set up, this may mean you need to add it to the default template, or to a "partial" or "include" template. If you can find where the site stylesheet is linked, that's probably the right place. Alternatively, you can include the script in your site using Netlify's Script Injection feature. When a user logs in with the Netlify Identity widget, an access token directs to the site homepage. In order to complete the login and get back to the CMS, redirect the user back to the /admin/ path. To do this, add the following script before the closing body tag of your site's main index page: Note: This example script requires modern JavaScript and does not work on IE11. For legacy browser support, use function expressions (function () {}) in place of the arrow functions (() => {}), or use a transpiler such as Babel. Accessing the CMS Your site CMS is now fully configured and ready for login! If you set your registration preference to "Invite only," invite yourself (and anyone else you choose) as a site user. To do this, select the Identity tab from your site dashboard, and then select the Invite users button. Invited users receive an email invitation with a confirmation link. Clicking the link will take you to your site with a login prompt. If you left your site registration open, or for return visits after confirming an email invitation, access your site's CMS at yoursite.com/admin/. Note: No matter where you access Netlify CMS — whether running locally, in a staging environment, or in your published site — it always fetches and commits files in your hosted repository (for example, on GitHub), on the branch you configured in your Netlify CMS config.yml file. This means that content fetched in the admin UI matches the content in the repository, which may be different from your locally running site. It also means that content saved using the admin UI saves directly to the hosted repository, even if you're running the UI locally or in staging. Examples Do you have a great, open source example? Submit a pull request to this page! Example Tools Type Source More info Gatsby & Netlify CMS Meetup Group Template Gatsby demo robertcoopercode/gatsby-netlify-cms blog post This Developing Journey middleman blog bdougie/blog blog post Jamstack Recipes Hugo, Azure demo hlaueriksson/jamstack-cms blog post Bael Vue, Nuxt blog jake-101/bael-template blog post Forest Garden Wales Hugo blog forestgardenwales/forestgarden.wales blog post Jekyll Demo Jekyll, Gulp demo NickStees/jekyll-cms read me Jekyll feat Alembic Theme Demo Jekyll demo DavidDarnes/alembic-netlifycms-kit read me Eleventy Starter Project Eleventy demo danurbanowicz/eleventy-netlify-boilerplate read me YellowCake - Complete website with blog Gatsby, Netlify-CMS, Uploadcare demo thriveweb/yellowcake blog post Vue.js - Nuxt.js Starter Project Vue, Nuxt demo renestalder/nuxt-netlify-cms-starter-template read me Hexo Demo Hexo demo DemoMacro/Hexo-NetlifyCMS read me Gitbook Demo Gitbook demo DemoMacro/Gitbook-NetlifyCMS read me VuePress Demo VuePress demo DemoMacro/VuePress-NetlifyCMS read me Jigsaw Blog Starter Template Demo Jigsaw demo erickpatrick/jigsaw-blog-netlify-netlifycms-template blog post Nuxt & NetlifyCMS Boilerplate Vue, Nuxt demo tylermercer/nuxt-netlifycms-boilerplate read me Next.js demo Next.js blog masives/netlifycms-nextjs read me Delog - Jamstack Blog with Netlify CMS Gatsby, Netlify-CMS demo W3Layouts/gatsby-starter-delog blog post Netlify CMS template for Gridsome Gridsome, Vue demo suits-at/netlifycms-gridsome read me Next.js blogging template for Netlify Next.js, Netlify blog wutali/nextjs-netlify-blog-template read me Netlify CMS and OAuth server on AWS Netlify, Pulumi, AWS blog pulumi/examples/aws-ts-netlify-cms-and-oauth blog post Eleventy Starter Boilerplate Eleventy, Netlify demo ixartz/Eleventy-Starter-Boilerplate read me Nuxt, Tailwind & NetlifyCMS Boilerplate Vue, Nuxt demo Knogobert/ntn-boilerplate read me Gatsby & Netlify CMS Personal Portfolio Gatsby portfolio EarlGeorge/React-Gatsby read me Gatsby This guide will help you get started using Netlify CMS and Gatsby. To get up and running with Gatsby, you'll need to have Node.js installed on your computer. Note: Gatsby's minimum supported Node.js version is Node 8. Create a new Gatsby site Let's create a new site using the default Gatsby Starter Blog. Run the following commands in the terminal, in the folder where you'd like to create the blog: Get to know Gatsby In your favorite code editor, open up the code generated for your "Gatsby Starter Blog" site, and take a look at the content directory. You will see that there are multiple Markdown files that represent blog posts. Open one .md file and you will see something like this: We can see above that each blog post has a title, a date, a description and a body. Now, let's recreate this using Netlify CMS. Add Netlify CMS to your site First let's install some dependencies. We'll need netlify-cms-app and gatsby-plugin-netlify-cms. Run the following command in the terminal at the root of your site: Configuration For the purpose of this guide we will deploy to Netlify from a GitHub repository which requires the minimum configuration. Create a config.yml file in the directory structure you see below: In your config.yml file paste the following configuration: Note: The above configuration allows assets to be stored relative to their content. Therefore posts would be stored in the format below as it is in gatsby-starter-blog. Finally, add the plugin to your gatsby-config.js. Push to GitHub It's now time to commit your changes and push to GitHub. The Gatsby starter initializes Git automatically for you, so you only need to do: Add your repo to Netlify Go to Netlify and select 'New Site from Git'. Select GitHub and the repository you just pushed to. Click Configure Netlify on GitHub and give access to your repository. Finish the setup by clicking Deploy Site. Netlify will begin reading your repository and starting building your project. Enable Identity and Git Gateway Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: Go to Settings > Identity, and select Enable Identity service. Under Registration preferences, select Open or Invite only. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under External providers. Scroll down to Services > Git Gateway, and click Enable Git Gateway. This authenticates with your Git host and generates an API access token. In this case, we're leaving the Roles field blank, which means any logged in user may access the CMS. For information on changing this, check the Netlify Identity documentation. Start publishing It's time to create your first blog post. Login to your site's /admin/ page and create a new post by clicking New Blog. Add a title, a date and some text. When you click Publish, a new commit will be created in your GitHub repo with this format Create Blog “year-month-date-title”. Then Netlify will detect that there was a commit in your repo, and will start rebuilding your project. When your project is deployed you'll be able to see the post you created. Cleanup It is now safe to remove the default Gatsby blog posts.
    https://bgoonz-blog.netlify.app/images/netlify-dee8d6ae.svg
  • Web-Dev-Hub
    September 11, 2021 Javascript Interview Questions Object Oriented JavaScript Javascript Interview Questions: What are the possible ways to create objects in JavaScript There are many ways to create objects in javascript as below Object constructor: The simplest way to create an empty object is using the Object constructor. Currently this approach is not recommended. var object = new Object(); Object's create method: The create method of Object creates a new object by passing the prototype object as a parameter var object = Object.create(null); Object literal syntax: The object literal syntax is equivalent to create method when it passes null as parameter var object = {}; Function constructor: Create any function and apply the new operator to create object instances, function Person(name) { this.name = name; this.age = 21; } var object = new Person('Sudheer'); Function constructor with prototype: This is similar to function constructor but it uses prototype for their properties and methods, function Person() {} Person.prototype.name = 'Sudheer'; var object = new Person(); This is equivalent to an instance created with an object create method with a function prototype and then call that function with an instance and parameters as arguments. function func {}; new func(x, y, z); (OR)// Create a new instance using function prototype. var newInstance = Object.create(func.prototype) // Call the function var result = func.call(newInstance, x, y, z), // If the result is a non-null object then use it otherwise just use the new instance. console.log(result && typeof result === 'object' ? result : newInstance); ES6 Class syntax: ES6 introduces class feature to create the objects class Person { constructor(name) { this.name = name; } } var object = new Person('Sudheer'); Singleton pattern: A Singleton is an object which can only be instantiated one time. Repeated calls to its constructor return the same instance and this way one can ensure that they don't accidentally create multiple instances. var object = new (function () { this.name = 'Sudheer'; })(); What is a prototype chain Prototype chaining is used to build new types of objects based on existing ones. It is similar to inheritance in a class based language. The prototype on object instance is available through Object.getPrototypeOf(object) or **proto** property whereas prototype on constructors function is available through Object.prototype. What is the difference between Call, Apply and Bind The difference between Call, Apply and Bind can be explained with below examples, Call: The call() method invokes a function with a given this value and arguments provided one by one var employee1 = { firstName: 'John', lastName: 'Rodson' }; var employee2 = { firstName: 'Jimmy', lastName: 'Baily' }; function invite(greeting1, greeting2) { console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName + ', ' + greeting2); } invite.call(employee1, 'Hello', 'How are you?'); // Hello John Rodson, How are you? invite.call(employee2, 'Hello', 'How are you?'); // Hello Jimmy Baily, How are you? Apply: Invokes the function with a given this value and allows you to pass in arguments as an array var employee1 = { firstName: 'John', lastName: 'Rodson' }; var employee2 = { firstName: 'Jimmy', lastName: 'Baily' }; function invite(greeting1, greeting2) { console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName + ', ' + greeting2); } invite.apply(employee1, ['Hello', 'How are you?']); // Hello John Rodson, How are you? invite.apply(employee2, ['Hello', 'How are you?']); // Hello Jimmy Baily, How are you? bind: returns a new function, allowing you to pass any number of arguments var employee1 = { firstName: 'John', lastName: 'Rodson' }; var employee2 = { firstName: 'Jimmy', lastName: 'Baily' }; function invite(greeting1, greeting2) { console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName + ', ' + greeting2); } var inviteEmployee1 = invite.bind(employee1); var inviteEmployee2 = invite.bind(employee2); inviteEmployee1('Hello', 'How are you?'); // Hello John Rodson, How are you? inviteEmployee2('Hello', 'How are you?'); // Hello Jimmy Baily, How are you? Call and apply are pretty interchangeable. Both execute the current function immediately. You need to decide whether it's easier to send in an array or a comma separated list of arguments. You can remember by treating Call is for comma (separated list) and Apply is for Array. Whereas Bind creates a new function that will have this set to the first parameter passed to bind(). What is JSON and its common operations JSON is a text-based data format following JavaScript object syntax, which was popularized by Douglas Crockford. It is useful when you want to transmit data across a network and it is basically just a text file with an extension of .json, and a MIME type of application/json Parsing: Converting a string to a native object JSON.parse(text); Stringification: converting a native object to a string so it can be transmitted across the network JSON.stringify(object); What is the purpose of the array slice method The slice() method returns the selected elements in an array as a new array object. It selects the elements starting at the given start argument, and ends at the given optional end argument without including the last element. If you omit the second argument then it selects till the end. Some of the examples of this method are, let arrayIntegers = [1, 2, 3, 4, 5]; let arrayIntegers1 = arrayIntegers.slice(0, 2); // returns [1,2] let arrayIntegers2 = arrayIntegers.slice(2, 3); // returns [3] let arrayIntegers3 = arrayIntegers.slice(4); //returns [5] Note: Slice method won't mutate the original array but it returns the subset as a new array. What is the purpose of the array splice method The splice() method is used either adds/removes items to/from an array, and then returns the removed item. The first argument specifies the array position for insertion or deletion whereas the optional second argument indicates the number of elements to be deleted. Each additional argument is added to the array. Some of the examples of this method are, let arrayIntegersOriginal1 = [1, 2, 3, 4, 5]; let arrayIntegersOriginal2 = [1, 2, 3, 4, 5]; let arrayIntegersOriginal3 = [1, 2, 3, 4, 5]; let arrayIntegers1 = arrayIntegersOriginal1.splice(0, 2); // returns [1, 2]; original array: [3, 4, 5] let arrayIntegers2 = arrayIntegersOriginal2.splice(3); // returns [4, 5]; original array: [1, 2, 3] let arrayIntegers3 = arrayIntegersOriginal3.splice(3, 1, 'a', 'b', 'c'); //returns [4]; original array: [1, 2, 3, "a", "b", "c", 5] Note: Splice method modifies the original array and returns the deleted array. What is the difference between slice and splice Some of the major difference in a tabular form Slice Splice Doesn't modify the original array(immutable) Modifies the original array(mutable) Returns the subset of original array Returns the deleted elements as array Used to pick the elements from array Used to insert or delete elements to/from array How do you compare Object and Map Objects are similar to Maps in that both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Due to this reason, Objects have been used as Maps historically. But there are important differences that make using a Map preferable in certain cases. The keys of an Object are Strings and Symbols, whereas they can be any value for a Map, including functions, objects, and any primitive. The keys in Map are ordered while keys added to Object are not. Thus, when iterating over it, a Map object returns keys in order of insertion. You can get the size of a Map easily with the size property, while the number of properties in an Object must be determined manually. A Map is an iterable and can thus be directly iterated, whereas iterating over an Object requires obtaining its keys in some fashion and iterating over them. An Object has a prototype, so there are default keys in the map that could collide with your keys if you're not careful. As of ES5 this can be bypassed by using map = Object.create(null), but this is seldom done. A Map may perform better in scenarios involving frequent addition and removal of key pairs. What is the difference between == and === operators JavaScript provides both strict(===, !==) and type-converting(==, !=) equality comparison. The strict operators take type of variable in consideration, while non-strict operators make type correction/conversion based upon values of variables. The strict operators follow the below conditions for different types, Two strings are strictly equal when they have the same sequence of characters, same length, and same characters in corresponding positions. Two numbers are strictly equal when they are numerically equal. i.e, Having the same number value. There are two special cases in this, NaN is not equal to anything, including NaN. Positive and negative zeros are equal to one another. Two Boolean operands are strictly equal if both are true or both are false. Two objects are strictly equal if they refer to the same Object. Null and Undefined types are not equal with ===, but equal with ==. i.e, null===undefined --> false but null==undefined --> true Some of the example which covers the above cases, 0 == false // true 0 === false // false 1 == "1" // true 1 === "1" // false null == undefined // true null === undefined // false '0' == false // true '0' === false // false []==[] or []===[] //false, refer different objects in memory {}=={} or {}==={} //false, refer different objects in memory What are lambda or arrow functions An arrow function is a shorter syntax for a function expression and does not have its own this, arguments, super, or new.target. These functions are best suited for non-method functions, and they cannot be used as constructors. What is a first class function In Javascript, functions are first class objects. First-class functions means when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable. For example, in the below example, handler functions assigned to a listener const handler = () => console.log('This is a click handler function'); document.addEventListener('click', handler); What is a first order function First-order function is a function that doesn't accept another function as an argument and doesn't return a function as its return value. const firstOrder = () => console.log('I am a first order function!'); What is a higher order function Higher-order function is a function that accepts another function as an argument or returns a function as a return value or both. const firstOrderFunc = () => console.log('Hello, I am a First order function'); const higherOrder = (ReturnFirstOrderFunc) => ReturnFirstOrderFunc(); higherOrder(firstOrderFunc); What is a unary function Unary function (i.e. monadic) is a function that accepts exactly one argument. It stands for a single argument accepted by a function. Let us take an example of unary function, const unaryFunction = (a) => console.log(a + 10); // Add 10 to the given argument and display the value What is the currying function Currying is the process of taking a function with multiple arguments and turning it into a sequence of functions each with only a single argument. Currying is named after a mathematician Haskell Curry. By applying currying, a n-ary function turns it into a unary function. Let's take an example of n-ary function and how it turns into a currying function, const multiArgFunction = (a, b, c) => a + b + c; console.log(multiArgFunction(1, 2, 3)); // 6 const curryUnaryFunction = (a) => (b) => (c) => a + b + c; curryUnaryFunction(1); // returns a function: b => c => 1 + b + c curryUnaryFunction(1)(2); // returns a function: c => 3 + c curryUnaryFunction(1)(2)(3); // returns the number 6 Curried functions are great to improve code reusability and functional composition. What is a pure function A Pure function is a function where the return value is only determined by its arguments without any side effects. i.e, If you call a function with the same arguments 'n' number of times and 'n' number of places in the application then it will always return the same value. Let's take an example to see the difference between pure and impure functions,//Impure let numberArray = []; const impureAddNumber = (number) => numberArray.push(number); //Pure const pureAddNumber = (number) => (argNumberArray) => argNumberArray.concat([number]); //Display the results console.log(impureAddNumber(6)); // returns 1 console.log(numberArray); // returns [6] console.log(pureAddNumber(7)(numberArray)); // returns [6, 7] console.log(numberArray); // returns [6] As per above code snippets, Push function is impure itself by altering the array and returning an push number index which is independent of parameter value. Whereas Concat on the other hand takes the array and concatenates it with the other array producing a whole new array without side effects. Also, the return value is a concatenation of the previous array. Remember that Pure functions are important as they simplify unit testing without any side effects and no need for dependency injection. They also avoid tight coupling and make it harder to break your application by not having any side effects. These principles are coming together with Immutability concept of ES6 by giving preference to const over let usage. What is the purpose of the let keyword The let statement declares a block scope local variable. Hence the variables defined with let keyword are limited in scope to the block, statement, or expression on which it is used. Whereas variables declared with the var keyword used to define a variable globally, or locally to an entire function regardless of block scope. Let's take an example to demonstrate the usage, let counter = 30; if (counter === 30) { let counter = 31; console.log(counter); // 31 } console.log(counter); // 30 (because the variable in if block won't exist here) What is the difference between let and var You can list out the differences in a tabular format var let It is been available from the beginning of JavaScript Introduced as part of ES6 It has function scope It has block scope Variables will be hoisted Hoisted but not initialized Let's take an example to see the difference, function userDetails(username) { if (username) { console.log(salary); // undefined due to hoisting console.log(age); // ReferenceError: Cannot access 'age' before initialization let age = 30; var salary = 10000; } console.log(salary); //10000 (accessible to due function scope) console.log(age); //error: age is not defined(due to block scope) } userDetails('John'); What is the reason to choose the name let as a keyword let is a mathematical statement that was adopted by early programming languages like Scheme and Basic. It has been borrowed from dozens of other languages that use let already as a traditional keyword as close to var as possible. How do you redeclare variables in switch block without an error If you try to redeclare variables in a switch block then it will cause errors because there is only one block. For example, the below code block throws a syntax error as below, let counter = 1; switch (x) { case 0: let name; break; case 1: let name; // SyntaxError for redeclaration. break; } To avoid this error, you can create a nested block inside a case clause and create a new block scoped lexical environment. let counter = 1; switch (x) { case 0: { let name; break; } case 1: { let name; // No SyntaxError for redeclaration. break; } } What is the Temporal Dead Zone The Temporal Dead Zone is a behavior in JavaScript that occurs when declaring a variable with the let and const keywords, but not with var. In ECMAScript 6, accessing a let or const variable before its declaration (within its scope) causes a ReferenceError. The time span when that happens, between the creation of a variable's binding and its declaration, is called the temporal dead zone. Let's see this behavior with an example, function somemethod() { console.log(counter1); // undefined console.log(counter2); // ReferenceError var counter1 = 1; let counter2 = 2; } What is IIFE(Immediately Invoked Function Expression) IIFE (Immediately Invoked Function Expression) is a JavaScript function that runs as soon as it is defined. The signature of it would be as below,(function () { // logic here })(); The primary reason to use an IIFE is to obtain data privacy because any variables declared within the IIFE cannot be accessed by the outside world. i.e, If you try to access variables with IIFE then it throws an error as below,(function () { var message = 'IIFE'; console.log(message); })(); console.log(message); //Error: message is not defined What is the benefit of using modules There are a lot of benefits to using modules in favour of a sprawling. Some of the benefits are, Maintainability Reusability Namespacing What is memoization Memoization is a programming technique which attempts to increase a function's performance by caching its previously computed results. Each time a memoized function is called, its parameters are used to index the cache. If the data is present, then it can be returned, without executing the entire function. Otherwise the function is executed and then the result is added to the cache. Let's take an example of adding function with memoization, const memoizAddition = () => { let cache = {}; return (value) => { if (value in cache) { console.log('Fetching from cache'); return cache[value]; // Here, cache.value cannot be used as property name starts with the number which is not a valid JavaScript identifier. Hence, can only be accessed using the square bracket notation. } else { console.log('Calculating result'); let result = value + 20; cache[value] = result; return result; } }; }; // returned function from memoizAddition const addition = memoizAddition(); console.log(addition(20)); //output: 40 calculated console.log(addition(20)); //output: 40 cached What is Hoisting Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution. Remember that JavaScript only hoists declarations, not initialisation. Let's take a simple example of variable hoisting, console.log(message); //output : undefined var message = 'The variable Has been hoisted'; The above code looks like as below to the interpreter, var message; console.log(message); message = 'The variable Has been hoisted'; What are classes in ES6 In ES6, Javascript classes are primarily syntactic sugar over JavaScript's existing prototype-based inheritance. For example, the prototype based inheritance written in function expression as below, function Bike(model, color) { this.model = model; this.color = color; } Bike.prototype.getDetails = function () { return this.model + ' bike has' + this.color + ' color'; }; Whereas ES6 classes can be defined as an alternative class Bike { constructor(color, model) { this.color = color; this.model = model; } getDetails() { return this.model + ' bike has' + this.color + ' color'; } } What are closures A closure is the combination of a function and the lexical environment within which that function was declared. i.e, It is an inner function that has access to the outer or enclosing function's variables. The closure has three scope chains Own scope where variables defined between its curly brackets Outer function's variables Global variables Let's take an example of closure concept, function Welcome(name) { var greetingInfo = function (message) { console.log(message + ' ' + name); }; return greetingInfo; } var myFunction = Welcome('John'); myFunction('Welcome '); //Output: Welcome John myFunction('Hello Mr.'); //output: Hello Mr.John As per the above code, the inner function(i.e, greetingInfo) has access to the variables in the outer function scope(i.e, Welcome) even after the outer function has returned. What are modules Modules refer to small units of independent, reusable code and also act as the foundation of many JavaScript design patterns. Most of the JavaScript modules export an object literal, a function, or a constructor Why do you need modules Below are the list of benefits using modules in javascript ecosystem Maintainability Reusability Namespacing What is scope in javascript Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime. In other words, scope determines the visibility of variables and other resources in areas of your code. What is a service worker A Service worker is basically a script (JavaScript file) that runs in the background, separate from a web page and provides features that don't need a web page or user interaction. Some of the major features of service workers are Rich offline experiences(offline first web application development), periodic background syncs, push notifications, intercept and handle network requests and programmatically managing a cache of responses. How do you manipulate DOM using a service worker Service worker can't access the DOM directly. But it can communicate with the pages it controls by responding to messages sent via the postMessage interface, and those pages can manipulate the DOM. How do you reuse information across service worker restarts The problem with service worker is that it gets terminated when not in use, and restarted when it's next needed, so you cannot rely on global state within a service worker's onfetch and onmessage handlers. In this case, service workers will have access to IndexedDB API in order to persist and reuse across restarts. What is IndexedDB IndexedDB is a low-level API for client-side storage of larger amounts of structured data, including files/blobs. This API uses indexes to enable high-performance searches of this data. What is web storage Web storage is an API that provides a mechanism by which browsers can store key/value pairs locally within the user's browser, in a much more intuitive fashion than using cookies. The web storage provides two mechanisms for storing data on the client. Local storage: It stores data for current origin with no expiration date. Session storage: It stores data for one session and the data is lost when the browser tab is closed. What is a post message Post message is a method that enables cross-origin communication between Window objects.(i.e, between a page and a pop-up that it spawned, or between a page and an iframe embedded within it). Generally, scripts on different pages are allowed to access each other if and only if the pages follow same-origin policy(i.e, pages share the same protocol, port number, and host). What is a Cookie A cookie is a piece of data that is stored on your computer to be accessed by your browser. Cookies are saved as key/value pairs. For example, you can create a cookie named username as below, document.cookie = 'username=John'; Why do you need a Cookie Cookies are used to remember information about the user profile(such as username). It basically involves two steps, When a user visits a web page, the user profile can be stored in a cookie. Next time the user visits the page, the cookie remembers the user profile. What are the options in a cookie There are few below options available for a cookie, By default, the cookie is deleted when the browser is closed but you can change this behavior by setting expiry date (in UTC time). document.cookie = 'username=John; expires=Sat, 8 Jun 2019 12:00:00 UTC'; By default, the cookie belongs to a current page. But you can tell the browser what path the cookie belongs to using a path parameter. document.cookie = 'username=John; path=/services'; How do you delete a cookie You can delete a cookie by setting the expiry date as a passed date. You don't need to specify a cookie value in this case. For example, you can delete a username cookie in the current page as below. document.cookie = 'username=; expires=Fri, 07 Jun 2019 00:00:00 UTC; path=/;'; Note: You should define the cookie path option to ensure that you delete the right cookie. Some browsers doesn't allow to delete a cookie unless you specify a path parameter. What are the differences between cookie, local storage and session storage Below are some of the differences between cookie, local storage and session storage, Feature Cookie Local storage Session storage Accessed on client or server side Both server-side & client-side client-side only client-side only Lifetime As configured using Expires option until deleted until tab is closed SSL support Supported Not supported Not supported Maximum data size 4KB 5 MB 5MB What is the main difference between localStorage and sessionStorage LocalStorage is the same as SessionStorage but it persists the data even when the browser is closed and reopened(i.e it has no expiration time) whereas in sessionStorage data gets cleared when the page session ends. How do you access web storage The Window object implements the WindowLocalStorage and WindowSessionStorage objects which has localStorage(window.localStorage) and sessionStorage(window.sessionStorage) properties respectively. These properties create an instance of the Storage object, through which data items can be set, retrieved and removed for a specific domain and storage type (session or local). For example, you can read and write on local storage objects as below localStorage.setItem('logo', document.getElementById('logo').value); localStorage.getItem('logo'); What are the methods available on session storage The session storage provided methods for reading, writing and clearing the session data// Save data to sessionStorage sessionStorage.setItem('key', 'value'); // Get saved data from sessionStorage let data = sessionStorage.getItem('key'); // Remove saved data from sessionStorage sessionStorage.removeItem('key'); // Remove all saved data from sessionStorage sessionStorage.clear(); What is a storage event and its event handler The StorageEvent is an event that fires when a storage area has been changed in the context of another document. Whereas onstorage property is an EventHandler for processing storage events. The syntax would be as below window.onstorage = functionRef; Let's take the example usage of onstorage event handler which logs the storage key and it's values window.onstorage = function (e) { console.log('The ' + e.key + ' key has been changed from ' + e.oldValue + ' to ' + e.newValue + '.'); }; Why do you need web storage Web storage is more secure, and large amounts of data can be stored locally, without affecting website performance. Also, the information is never transferred to the server. Hence this is a more recommended approach than Cookies. How do you check web storage browser support You need to check browser support for localStorage and sessionStorage before using web storage, if (typeof Storage !== 'undefined') { // Code for localStorage/sessionStorage. } else { // Sorry! No Web Storage support.. } How do you check web workers browser support You need to check browser support for web workers before using it if (typeof Worker !== 'undefined') { // code for Web worker support. } else { // Sorry! No Web Worker support.. } Give an example of a web worker You need to follow below steps to start using web workers for counting example Create a Web Worker File: You need to write a script to increment the count value. Let's name it as counter.js let i = 0; function timedCount() { i = i + 1; postMessage(i); setTimeout('timedCount()', 500); } timedCount(); Here postMessage() method is used to post a message back to the HTML page Create a Web Worker Object: You can create a web worker object by checking for browser support. Let's name this file as web worker example.js if (typeof w == 'undefined') { w = new Worker('counter.js'); } and we can receive messages from web worker w.onmessage = function (event) { document.getElementById('message').innerHTML = event.data; }; Terminate a Web Worker: Web workers will continue to listen for messages (even after the external script is finished) until it is terminated. You can use the terminate() method to terminate listening to the messages. w.terminate(); Reuse the Web Worker: If you set the worker variable to undefined you can reuse the code w = undefined; What are the restrictions of web workers on DOM WebWorkers don't have access to below javascript objects since they are defined in an external files Window object Document object Parent object What is a promise A promise is an object that may produce a single value some time in the future with either a resolved value or a reason that it's not resolved(for example, network error). It will be in one of the 3 possible states: fulfilled, rejected, or pending. The syntax of Promise creation looks like below, const promise = new Promise(function (resolve, reject) { // promise description }); The usage of a promise would be as below, const promise = new Promise( (resolve) => { setTimeout(() => { resolve("I'm a Promise!"); }, 5000); }, (reject) => {} ); promise.then((value) => console.log(value)); The action flow of a promise will be as below, Why do you need a promise Promises are used to handle asynchronous operations. They provide an alternative approach for callbacks by reducing the callback hell and writing the cleaner code. What are the three states of promise Promises have three states: Pending: This is an initial state of the Promise before an operation begins Fulfilled: This state indicates that the specified operation was completed. Rejected: This state indicates that the operation did not complete. In this case an error value will be thrown. What is a callback function A callback function is a function passed into another function as an argument. This function is invoked inside the outer function to complete an action. Let's take a simple example of how to use callback function function callbackFunction(name) { console.log('Hello ' + name); } function outerFunction(callback) { let name = prompt('Please enter your name.'); callback(name); } outerFunction(callbackFunction); Why do we need callbacks The callbacks are needed because javascript is an event driven language. That means instead of waiting for a response javascript will keep executing while listening for other events. Let's take an example with the first function invoking an API call(simulated by setTimeout) and the next function which logs the message. function firstFunction() { // Simulate a code delay setTimeout(function () { console.log('First function called'); }, 1000); } function secondFunction() { console.log('Second function called'); } firstFunction(); secondFunction(); Output; // Second function called // First function called As observed from the output, javascript didn't wait for the response of the first function and the remaining code block got executed. So callbacks are used in a way to make sure that certain code doesn't execute until the other code finishes execution. What is a callback hell Callback Hell is an anti-pattern with multiple nested callbacks which makes code hard to read and debug when dealing with asynchronous logic. The callback hell looks like below, async1(function(){ async2(function(){ async3(function(){ async4(function(){ .... }); }); }); }); What are server-sent events Server-sent events (SSE) is a server push technology enabling a browser to receive automatic updates from a server via HTTP connection without resorting to polling. These are a one way communications channel - events flow from server to client only. This has been used in Facebook/Twitter updates, stock price updates, news feeds etc. How do you receive server-sent event notifications The EventSource object is used to receive server-sent event notifications. For example, you can receive messages from server as below, if (typeof EventSource !== 'undefined') { var source = new EventSource('sse_generator.js'); source.onmessage = function (event) { document.getElementById('output').innerHTML += event.data + '<br>'; }; } How do you check browser support for server-sent events You can perform browser support for server-sent events before using it as below, if (typeof EventSource !== 'undefined') { // Server-sent events supported. Let's have some code here! } else { // No server-sent events supported } What are the events available for server sent events Below are the list of events available for server sent events | Event | Description | |---- | --------- | onopen | It is used when a connection to the server is opened | | onmessage | This event is used when a message is received | | onerror | It happens when an error occurs| What are the main rules of promise A promise must follow a specific set of rules, A promise is an object that supplies a standard-compliant .then() method A pending promise may transition into either fulfilled or rejected state A fulfilled or rejected promise is settled and it must not transition into any other state. Once a promise is settled, the value must not change. What is callback in callback You can nest one callback inside in another callback to execute the actions sequentially one by one. This is known as callbacks in callbacks. loadScript('/script1.js', function (script) { console.log('first script is loaded'); loadScript('/script2.js', function (script) { console.log('second script is loaded'); loadScript('/script3.js', function (script) { console.log('third script is loaded'); // after all scripts are loaded }); }); }); What is promise chaining The process of executing a sequence of asynchronous tasks one after another using promises is known as Promise chaining. Let's take an example of promise chaining for calculating the final result, new Promise(function (resolve, reject) { setTimeout(() => resolve(1), 1000); }) .then(function (result) { console.log(result); // 1 return result * 2; }) .then(function (result) { console.log(result); // 2 return result * 3; }) .then(function (result) { console.log(result); // 6 return result * 4; }); In the above handlers, the result is passed to the chain of .then() handlers with the below work flow, The initial promise resolves in 1 second, After that .then handler is called by logging the result(1) and then return a promise with the value of result * 2. After that the value passed to the next .then handler by logging the result(2) and return a promise with result * 3. Finally the value passed to the last .then handler by logging the result(6) and return a promise with result * 4. What is promise.all Promise.all is a promise that takes an array of promises as an input (an iterable), and it gets resolved when all the promises get resolved or any one of them gets rejected. For example, the syntax of promise.all method is below, Promise.all([Promise1, Promise2, Promise3]) .then(result) => { console.log(result) }) .catch(error => console.log(`Error in promises ${error}`)) Note: Remember that the order of the promises(output the result) is maintained as per input order. What is the purpose of the race method in promise Promise.race() method will return the promise instance which is firstly resolved or rejected. Let's take an example of race() method where promise2 is resolved first var promise1 = new Promise(function (resolve, reject) { setTimeout(resolve, 500, 'one'); }); var promise2 = new Promise(function (resolve, reject) { setTimeout(resolve, 100, 'two'); }); Promise.race([promise1, promise2]).then(function (value) { console.log(value); // "two" // Both promises will resolve, but promise2 is faster }); What is a strict mode in javascript Strict Mode is a new feature in ECMAScript 5 that allows you to place a program, or a function, in a “strict” operating context. This way it prevents certain actions from being taken and throws more exceptions. The literal expression "use strict"; instructs the browser to use the javascript code in the Strict mode. Why do you need strict mode Strict mode is useful to write "secure" JavaScript by notifying "bad syntax" into real errors. For example, it eliminates accidentally creating a global variable by throwing an error and also throws an error for assignment to a non-writable property, a getter-only property, a non-existing property, a non-existing variable, or a non-existing object. How do you declare strict mode The strict mode is declared by adding "use strict"; to the beginning of a script or a function. If declared at the beginning of a script, it has global scope.'use strict'; x = 3.14; // This will cause an error because x is not declared and if you declare inside a function, it has local scope x = 3.14; // This will not cause an error. myFunction(); function myFunction() { 'use strict'; y = 3.14; // This will cause an error } What is the purpose of double exclamation The double exclamation or negation(!!) ensures the resulting type is a boolean. If it was falsey (e.g. 0, null, undefined, etc.), it will be false, otherwise, true. For example, you can test IE version using this expression as below, let isIE8 = false; isIE8 = !!navigator.userAgent.match(/MSIE 8.0/); console.log(isIE8); // returns true or false If you don't use this expression then it returns the original value. console.log(navigator.userAgent.match(/MSIE 8.0/)); // returns either an Array or null Note: The expression !! is not an operator, but it is just twice of ! operator. What is the purpose of the delete operator The delete keyword is used to delete the property as well as its value. var user = { name: 'John', age: 20 }; delete user.age; console.log(user); // {name: "John"} What is the typeof operator You can use the JavaScript typeof operator to find the type of a JavaScript variable. It returns the type of a variable or an expression. typeof 'John Abraham'; // Returns "string" typeof (1 + 2); // Returns "number" What is undefined property The undefined property indicates that a variable has not been assigned a value, or not declared at all. The type of undefined value is undefined too. var user; // Value is undefined, type is undefined console.log(typeof user); //undefined Any variable can be emptied by setting the value to undefined. user = undefined; What is null value The value null represents the intentional absence of any object value. It is one of JavaScript's primitive values. The type of null value is object. You can empty the variable by setting the value to null. var user = null; console.log(typeof user); //object What is the difference between null and undefined Below are the main differences between null and undefined, Null Undefined It is an assignment value which indicates that variable points to no object. It is not an assignment value where a variable has been declared but has not yet been assigned a value. Type of null is object Type of undefined is undefined The null value is a primitive value that represents the null, empty, or non-existent reference. The undefined value is a primitive value used when a variable has not been assigned a value. Indicates the absence of a value for a variable Indicates absence of variable itself Converted to zero (0) while performing primitive operations Converted to NaN while performing primitive operations What is eval The eval() function evaluates JavaScript code represented as a string. The string can be a JavaScript expression, variable, statement, or sequence of statements. console.log(eval('1 + 2')); // 3 What is the difference between window and document Below are the main differences between window and document, Window Document It is the root level element in any web page It is the direct child of the window object. This is also known as Document Object Model(DOM) By default window object is available implicitly in the page You can access it via window.document or document. It has methods like alert(), confirm() and properties like document, location It provides methods like getElementById, getElementsByTagName, createElement etc How do you access history in javascript The window.history object contains the browser's history. You can load previous and next URLs in the history using back() and next() methods. function goBack() { window.history.back(); } function goForward() { window.history.forward(); } Note: You can also access history without window prefix. How do you detect caps lock key turned on or not The mouseEvent getModifierState() is used to return a boolean value that indicates whether the specified modifier key is activated or not. The modifiers such as CapsLock, ScrollLock and NumLock are activated when they are clicked, and deactivated when they are clicked again. Let's take an input element to detect the CapsLock on/off behavior with an example,<input type="password" onmousedown="enterInput(event)" /> <p id="feedback"></p> <script> function enterInput(e) { var flag = e.getModifierState('CapsLock'); if (flag) { document.getElementById('feedback').innerHTML = 'CapsLock activated'; } else { document.getElementById('feedback').innerHTML = 'CapsLock not activated'; } } </script> What is isNaN The isNaN() function is used to determine whether a value is an illegal number (Not-a-Number) or not. i.e, This function returns true if the value equates to NaN. Otherwise it returns false. isNaN('Hello'); //true isNaN('100'); //false What are the differences between undeclared and undefined variables Below are the major differences between undeclared and undefined variables, undeclared undefined These variables do not exist in a program and are not declared These variables declared in the program but have not assigned any value If you try to read the value of an undeclared variable, then a runtime error is encountered If you try to read the value of an undefined variable, an undefined value is returned. What are global variables Global variables are those that are available throughout the length of the code without any scope. The var keyword is used to declare a local variable but if you omit it then it will become global variable msg = 'Hello'; // var is missing, it becomes global variable What are the problems with global variables The problem with global variables is the conflict of variable names of local and global scope. It is also difficult to debug and test the code that relies on global variables. What is NaN property The NaN property is a global property that represents "Not-a-Number" value. i.e, It indicates that a value is not a legal number. It is very rare to use NaN in a program but it can be used as return value for few cases Math.sqrt(-1); parseInt('Hello'); What is the purpose of isFinite function The isFinite() function is used to determine whether a number is a finite, legal number. It returns false if the value is +infinity, -infinity, or NaN (Not-a-Number), otherwise it returns true. isFinite(Infinity); // false isFinite(NaN); // false isFinite(-Infinity); // false isFinite(100); // true What is an event flow Event flow is the order in which event is received on the web page. When you click an element that is nested in various other elements, before your click actually reaches its destination, or target element, it must trigger the click event for each of its parent elements first, starting at the top with the global window object. There are two ways of event flow Top to Bottom(Event Capturing) Bottom to Top (Event Bubbling) What is event bubbling Event bubbling is a type of event propagation where the event first triggers on the innermost target element, and then successively triggers on the ancestors (parents) of the target element in the same nesting hierarchy till it reaches the outermost DOM element. What is event capturing Event capturing is a type of event propagation where the event is first captured by the outermost element, and then successively triggers on the descendants (children) of the target element in the same nesting hierarchy till it reaches the innermost DOM element. How do you submit a form using JavaScript You can submit a form using document.forms[0].submit(). All the form input's information is submitted using onsubmit event handler function submit() { document.forms[0].submit(); } How do you find operating system details The window.navigator object contains information about the visitor's browser OS details. Some of the OS properties are available under platform property, console.log(navigator.platform); What is the difference between document load and DOMContentLoaded events The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for assets(stylesheets, images, and subframes) to finish loading. Whereas The load event is fired when the whole page has loaded, including all dependent resources(stylesheets, images). What is the difference between native, host and user objects Native objects are objects that are part of the JavaScript language defined by the ECMAScript specification. For example, String, Math, RegExp, Object, Function etc core objects defined in the ECMAScript spec. Host objects are objects provided by the browser or runtime environment (Node). For example, window, XmlHttpRequest, DOM nodes etc are considered as host objects. User objects are objects defined in the javascript code. For example, User objects created for profile information. What are the tools or techniques used for debugging JavaScript code You can use below tools or techniques for debugging javascript Chrome Devtools debugger statement Good old console.log statement What are the pros and cons of promises over callbacks Below are the list of pros and cons of promises over callbacks, Pros: It avoids callback hell which is unreadable Easy to write sequential asynchronous code with .then() Easy to write parallel asynchronous code with Promise.all() Solves some of the common problems of callbacks(call the callback too late, too early, many times and swallow errors/exceptions) Cons: It makes little complex code You need to load a polyfill if ES6 is not supported What is the difference between an attribute and a property Attributes are defined on the HTML markup whereas properties are defined on the DOM. For example, the below HTML element has 2 attributes type and value,<input type="text" value="Name:"> You can retrieve the attribute value as below, const input = document.querySelector('input'); console.log(input.getAttribute('value')); // Good morning console.log(input.value); // Good morning And after you change the value of the text field to "Good evening", it becomes like console.log(input.getAttribute('value')); // Good morning console.log(input.value); // Good evening What is same-origin policy The same-origin policy is a policy that prevents JavaScript from making requests across domain boundaries. An origin is defined as a combination of URI scheme, hostname, and port number. If you enable this policy then it prevents a malicious script on one page from obtaining access to sensitive data on another web page using Document Object Model(DOM). What is the purpose of void 0 Void(0) is used to prevent the page from refreshing. This will be helpful to eliminate the unwanted side-effect, because it will return the undefined primitive value. It is commonly used for HTML documents that use href="JavaScript:Void(0);" within an <a> element. i.e, when you click a link, the browser loads a new page or refreshes the same page. But this behavior will be prevented using this expression. For example, the below link notify the message without reloading the page<a href="JavaScript:void(0);" onclick="alert('Well done!')"> Click Me! </a> Is JavaScript a compiled or interpreted language JavaScript is an interpreted language, not a compiled language. An interpreter in the browser reads over the JavaScript code, interprets each line, and runs it. Nowadays modern browsers use a technology known as Just-In-Time (JIT) compilation, which compiles JavaScript to executable bytecode just as it is about to run. Is JavaScript a case-sensitive language Yes, JavaScript is a case sensitive language. The language keywords, variables, function & object names, and any other identifiers must always be typed with a consistent capitalization of letters. Is there any relation between Java and JavaScript No, they are entirely two different programming languages and have nothing to do with each other. But both of them are Object Oriented Programming languages and like many other languages, they follow similar syntax for basic features(if, else, for, switch, break, continue etc). What are events Events are "things" that happen to HTML elements. When JavaScript is used in HTML pages, JavaScript can react on these events. Some of the examples of HTML events are, Web page has finished loading Input field was changed Button was clicked Let's describe the behavior of click event for button element,<!doctype html> <html> <head> <script> function greeting() { alert('Hello! Good morning'); } </script> </head> <body> <button type="button" onclick="greeting()">Click me</button> </body> </html> Who created javascript JavaScript was created by Brendan Eich in 1995 during his time at Netscape Communications. Initially it was developed under the name Mocha, but later the language was officially called LiveScript when it first shipped in beta releases of Netscape. What is the use of preventDefault method The preventDefault() method cancels the event if it is cancelable, meaning that the default action or behaviour that belongs to the event will not occur. For example, prevent form submission when clicking on submit button and prevent opening the page URL when clicking on hyperlink are some common use cases. document.getElementById('link').addEventListener('click', function (event) { event.preventDefault(); }); Note: Remember that not all events are cancelable. What is the use of stopPropagation method The stopPropagation method is used to stop the event from bubbling up the event chain. For example, the below nested divs with stopPropagation method prevents default event propagation when clicking on nested div(Div1)<p>Click DIV1 Element</p> <div onclick="secondFunc()">DIV 2 <div onclick="firstFunc(event)">DIV 1</div> </div> <script> function firstFunc(event) { alert("DIV 1"); event.stopPropagation(); } function secondFunc() { alert("DIV 2"); } </script> What are the steps involved in return false usage The return false statement in event handlers performs the below steps, First it stops the browser's default action or behaviour. It prevents the event from propagating the DOM Stops callback execution and returns immediately when called. What is BOM The Browser Object Model (BOM) allows JavaScript to "talk to" the browser. It consists of the objects navigator, history, screen, location and document which are children of the window. The Browser Object Model is not standardized and can change based on different browsers. What is the use of setTimeout The setTimeout() method is used to call a function or evaluate an expression after a specified number of milliseconds. For example, let's log a message after 2 seconds using setTimeout method, setTimeout(function () { console.log('Good morning'); }, 2000); What is the use of setInterval The setInterval() method is used to call a function or evaluate an expression at specified intervals (in milliseconds). For example, let's log a message after 2 seconds using setInterval method, setInterval(function () { console.log('Good morning'); }, 2000); Why is JavaScript treated as Single threaded JavaScript is a single-threaded language. Because the language specification does not allow the programmer to write code so that the interpreter can run parts of it in parallel in multiple threads or processes. Whereas languages like java, go, C++ can make multi-threaded and multi-process programs. What is an event delegation Event delegation is a technique for listening to events where you delegate a parent element as the listener for all of the events that happen inside it. For example, if you wanted to detect field changes in inside a specific form, you can use event delegation technique, var form = document.querySelector('#registration-form'); // Listen for changes to fields inside the form form.addEventListener( 'input', function (event) { // Log the field that was changed console.log(event.target); }, false ); What is ECMAScript ECMAScript is the scripting language that forms the basis of JavaScript. ECMAScript standardized by the ECMA International standards organization in the ECMA-262 and ECMA-402 specifications. The first edition of ECMAScript was released in 1997. What is JSON JSON (JavaScript Object Notation) is a lightweight format that is used for data interchanging. It is based on a subset of JavaScript language in the way objects are built in JavaScript. What are the syntax rules of JSON Below are the list of syntax rules of JSON The data is in name/value pairs The data is separated by commas Curly braces hold objects Square brackets hold arrays What is the purpose JSON stringify When sending data to a web server, the data has to be in a string format. You can achieve this by converting JSON object into a string using stringify() method. var userJSON = { name: 'John', age: 31 }; var userString = JSON.stringify(user); console.log(userString); //"{"name":"John","age":31}" How do you parse JSON string When receiving the data from a web server, the data is always in a string format. But you can convert this string value to a javascript object using parse() method. var userString = '{"name":"John","age":31}'; var userJSON = JSON.parse(userString); console.log(userJSON); // {name: "John", age: 31} Why do you need JSON When exchanging data between a browser and a server, the data can only be text. Since JSON is text only, it can easily be sent to and from a server, and used as a data format by any programming language. What are PWAs Progressive web applications (PWAs) are a type of mobile app delivered through the web, built using common web technologies including HTML, CSS and JavaScript. These PWAs are deployed to servers, accessible through URLs, and indexed by search engines. What is the purpose of clearTimeout method The clearTimeout() function is used in javascript to clear the timeout which has been set by setTimeout()function before that. i.e, The return value of setTimeout() function is stored in a variable and it's passed into the clearTimeout() function to clear the timer. For example, the below setTimeout method is used to display the message after 3 seconds. This timeout can be cleared by the clearTimeout() method.<script> var msg; function greeting() { alert('Good morning'); } function start() { msg =setTimeout(greeting, 3000); } function stop() { clearTimeout(msg); } </script> What is the purpose of clearInterval method The clearInterval() function is used in javascript to clear the interval which has been set by setInterval() function. i.e, The return value returned by setInterval() function is stored in a variable and it's passed into the clearInterval() function to clear the interval. For example, the below setInterval method is used to display the message for every 3 seconds. This interval can be cleared by the clearInterval() method.<script> var msg; function greeting() { alert('Good morning'); } function start() { msg = setInterval(greeting, 3000); } function stop() { clearInterval(msg); } </script> How do you redirect new page in javascript In vanilla javascript, you can redirect to a new page using the location property of window object. The syntax would be as follows, function redirect() { window.location.href = 'newPage.html'; } How do you check whether a string contains a substring There are 3 possible ways to check whether a string contains a substring or not, Using includes: ES6 provided String.prototype.includes method to test a string contains a substring var mainString = 'hello', subString = 'hell'; mainString.includes(subString); Using indexOf: In an ES5 or older environment, you can use String.prototype.indexOf which returns the index of a substring. If the index value is not equal to -1 then it means the substring exists in the main string. var mainString = 'hello', subString = 'hell'; mainString.indexOf(subString) !== -1; Using RegEx: The advanced solution is using Regular expression's test method( RegExp.test), which allows for testing for against regular expressions var mainString = 'hello', regex = /hell/; regex.test(mainString); How do you validate an email in javascript You can validate an email in javascript using regular expressions. It is recommended to do validations on the server side instead of the client side. Because the javascript can be disabled on the client side. function validateEmail(email) { var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(String(email).toLowerCase()); } The above regular expression accepts unicode characters. How do you get the current url with javascript You can use window.location.href expression to get the current url path and you can use the same expression for updating the URL too. You can also use document.URL for read-only purposes but this solution has issues in FF. console.log('location.href', window.location.href); // Returns full URL What are the various url properties of location object The below Location object properties can be used to access URL components of the page, href - The entire URL protocol - The protocol of the URL host - The hostname and port of the URL hostname - The hostname of the URL port - The port number in the URL pathname - The path name of the URL search - The query portion of the URL hash - The anchor portion of the URL How do get query string values in javascript You can use URLSearchParams to get query string values in javascript. Let's see an example to get the client code value from URL query string, const urlParams = new URLSearchParams(window.location.search); const clientCode = urlParams.get('clientCode'); How do you check if a key exists in an object You can check whether a key exists in an object or not using three approaches, Using in operator: You can use the in operator whether a key exists in an object or not'key' in obj; and If you want to check if a key doesn't exist, remember to use parenthesis,!('key' in obj); Using hasOwnProperty method: You can use hasOwnProperty to particularly test for properties of the object instance (and not inherited properties) obj.hasOwnProperty('key'); // true Using undefined comparison: If you access a non-existing property from an object, the result is undefined. Let's compare the properties against undefined to determine the existence of the property. const user = { name: 'John' }; console.log(user.name !== undefined); // true console.log(user.nickName !== undefined); // false How do you loop through or enumerate javascript object You can use the for-in loop to loop through javascript object. You can also make sure that the key you get is an actual property of an object, and doesn't come from the prototype using hasOwnProperty method. var object = { k1: 'value1', k2: 'value2', k3: 'value3' }; for (var key in object) { if (object.hasOwnProperty(key)) { console.log(key + ' -> ' + object[key]); // k1 -> value1 ... } } How do you test for an empty object There are different solutions based on ECMAScript versions Using Object entries(ECMA 7+): You can use object entries length along with constructor type. Object.entries(obj).length === 0 && obj.constructor === Object; // Since date object length is 0, you need to check constructor check as well Using Object keys(ECMA 5+): You can use object keys length along with constructor type. Object.keys(obj).length === 0 && obj.constructor === Object; // Since date object length is 0, you need to check constructor check as well Using for-in with hasOwnProperty(Pre-ECMA 5): You can use a for-in loop along with hasOwnProperty. function isEmpty(obj) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { return false; } } return JSON.stringify(obj) === JSON.stringify({}); } What is an arguments object The arguments object is an Array-like object accessible inside functions that contains the values of the arguments passed to that function. For example, let's see how to use arguments object inside sum function, function sum() { var total = 0; for (var i = 0, len = arguments.length; i < len; ++i) { total += arguments[i]; } return total; } sum(1, 2, 3); // returns 6 Note: You can't apply array methods on arguments object. But you can convert into a regular array as below. var argsArray = Array.prototype.slice.call(arguments); How do you make first letter of the string in an uppercase You can create a function which uses a chain of string methods such as charAt, toUpperCase and slice methods to generate a string with the first letter in uppercase. function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } What are the pros and cons of for loop The for-loop is a commonly used iteration syntax in javascript. It has both pros and cons Pros Works on every environment You can use break and continue flow control statements Cons Too verbose Imperative You might face one-by-off errors How do you display the current date in javascript You can use new Date() to generate a new Date object containing the current date and time. For example, let's display the current date in mm/dd/yyyy var today = new Date(); var dd = String(today.getDate()).padStart(2, '0'); var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0! var yyyy = today.getFullYear(); today = mm + '/' + dd + '/' + yyyy; document.write(today); How do you compare two date objects You need to use date.getTime() method to compare date values instead of comparison operators (==, !=, ===, and !== operators) var d1 = new Date(); var d2 = new Date(d1); console.log(d1.getTime() === d2.getTime()); //True console.log(d1 === d2); // False How do you check if a string starts with another string You can use ECMAScript 6's String.prototype.startsWith() method to check if a string starts with another string or not. But it is not yet supported in all browsers. Let's see an example to see this usage,'Good morning'.startsWith('Good'); // true 'Good morning'.startsWith('morning'); // false How do you trim a string in javascript JavaScript provided a trim method on string types to trim any whitespaces present at the beginning or ending of the string.' Hello World '.trim(); //Hello World If your browser(<IE9) doesn't support this method then you can use below polyfill. if (!String.prototype.trim) { (function () { // Make sure we trim BOM and NBSP var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; String.prototype.trim = function () { return this.replace(rtrim, ''); }; })(); } How do you add a key value pair in javascript There are two possible solutions to add new properties to an object. Let's take a simple object to explain these solutions. var object = { key1: value1, key2: value2 }; Using dot notation: This solution is useful when you know the name of the property object.key3 = 'value3'; Using square bracket notation: This solution is useful when the name of the property is dynamically determined. obj['key3'] = 'value3'; Is the !-- notation represents a special operator No,that's not a special operator. But it is a combination of 2 standard operators one after the other, A logical not (!) A prefix decrement (--) At first, the value decremented by one and then tested to see if it is equal to zero or not for determining the truthy/falsy value. How do you assign default values to variables You can use the logical or operator || in an assignment expression to provide a default value. The syntax looks like as below, var a = b || c; As per the above expression, variable 'a 'will get the value of 'c' only if 'b' is falsy (if is null, false, undefined, 0, empty string, or NaN), otherwise 'a' will get the value of 'b'. How do you define multiline strings You can define multiline string literals using the '\' character followed by line terminator. var str = 'This is a \ very lengthy \ sentence!'; But if you have a space after the '\' character, the code will look exactly the same, but it will raise a SyntaxError. What is an app shell model An application shell (or app shell) architecture is one way to build a Progressive Web App that reliably and instantly loads on your users' screens, similar to what you see in native applications. It is useful for getting some initial HTML to the screen fast without a network. Can we define properties for functions Yes, We can define properties for functions because functions are also objects. fn = function (x) { //Function code goes here }; fn.name = 'John'; fn.profile = function (y) { //Profile code goes here }; What is the way to find the number of parameters expected by a function You can use function.length syntax to find the number of parameters expected by a function. Let's take an example of sum function to calculate the sum of numbers, function sum(num1, num2, num3, num4) { return num1 + num2 + num3 + num4; } sum.length; // 4 is the number of parameters expected. What is a polyfill A polyfill is a piece of JS code used to provide modern functionality on older browsers that do not natively support it. For example, Silverlight plugin polyfill can be used to mimic the functionality of an HTML Canvas element on Microsoft Internet Explorer 7. What are break and continue statements The break statement is used to "jump out" of a loop. i.e, It breaks the loop and continues executing the code after the loop. for (i = 0; i < 10; i++) { if (i === 5) { break; } text += 'Number: ' + i + '<br>'; } The continue statement is used to "jump over" one iteration in the loop. i.e, It breaks one iteration (in the loop), if a specified condition occurs, and continues with the next iteration in the loop. for (i = 0; i < 10; i++) { if (i === 5) { continue; } text += 'Number: ' + i + '<br>'; } What are js labels The label statement allows us to name loops and blocks in JavaScript. We can then use these labels to refer back to the code later. For example, the below code with labels avoids printing the numbers when they are same, var i, j; loop1: for (i = 0; i < 3; i++) { loop2: for (j = 0; j < 3; j++) { if (i === j) { continue loop1; } console.log('i = ' + i + ', j = ' + j); } } // Output is: // "i = 1, j = 0" // "i = 2, j = 0" // "i = 2, j = 1" What are the benefits of keeping declarations at the top It is recommended to keep all declarations at the top of each script or function. The benefits of doing this are, Gives cleaner code It provides a single place to look for local variables Easy to avoid unwanted global variables It reduces the possibility of unwanted re-declarations What are the benefits of initializing variables It is recommended to initialize variables because of the below benefits, It gives cleaner code It provides a single place to initialize variables Avoid undefined values in the code What are the recommendations to create new object It is recommended to avoid creating new objects using new Object(). Instead you can initialize values based on it's type to create the objects. Assign {} instead of new Object() Assign "" instead of new String() Assign 0 instead of new Number() Assign false instead of new Boolean() Assign [] instead of new Array() Assign /()/ instead of new RegExp() Assign function (){} instead of new Function() You can define them as an example, var v1 = {}; var v2 = ''; var v3 = 0; var v4 = false; var v5 = []; var v6 = /()/; var v7 = function () {}; How do you define JSON arrays JSON arrays are written inside square brackets and arrays contain javascript objects. For example, the JSON array of users would be as below,"users":[ {"firstName":"John", "lastName":"Abrahm"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Shane", "lastName":"Warn"} ] How do you generate random integers You can use Math.random() with Math.floor() to return random integers. For example, if you want generate random integers between 1 to 10, the multiplication factor should be 10, Math.floor(Math.random() * 10) + 1; // returns a random integer from 1 to 10 Math.floor(Math.random() * 100) + 1; // returns a random integer from 1 to 100 Note: Math.random() returns a random number between 0 (inclusive), and 1 (exclusive) Can you write a random integers function to print integers with in a range Yes, you can create a proper random function to return a random number between min and max (both included) function randomInteger(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } randomInteger(1, 100); // returns a random integer from 1 to 100 randomInteger(1, 1000); // returns a random integer from 1 to 1000 What is tree shaking Tree shaking is a form of dead code elimination. It means that unused modules will not be included in the bundle during the build process and for that it relies on the static structure of ES2015 module syntax,( i.e. import and export). Initially this has been popularized by the ES2015 module bundler rollup. What is the need of tree shaking Tree Shaking can significantly reduce the code size in any application. i.e, The less code we send over the wire the more performant the application will be. For example, if we just want to create a “Hello World” Application using SPA frameworks then it will take around a few MBs, but by tree shaking it can bring down the size to just a few hundred KBs. Tree shaking is implemented in Rollup and Webpack bundlers. Is it recommended to use eval No, it allows arbitrary code to be run which causes a security problem. As we know that the eval() function is used to run text as code. In most of the cases, it should not be necessary to use it. What is a Regular Expression A regular expression is a sequence of characters that forms a search pattern. You can use this search pattern for searching data in a text. These can be used to perform all types of text search and text replace operations. Let's see the syntax format now,/pattern/modifiers; For example, the regular expression or search pattern with case-insensitive username would be,/John/i; What are the string methods available in Regular expression Regular Expressions has two string methods: search() and replace(). The search() method uses an expression to search for a match, and returns the position of the match. var msg = 'Hello John'; var n = msg.search(/John/i); // 6 The replace() method is used to return a modified string where the pattern is replaced. var msg = 'Hello John'; var n = msg.replace(/John/i, 'Buttler'); // Hello Buttler What are modifiers in regular expression Modifiers can be used to perform case-insensitive and global searches. Let's list down some of the modifiers, Modifier Description i Perform case-insensitive matching g Perform a global match rather than stops at first match m Perform multiline matching Let's take an example of global modifier, var text = 'Learn JS one by one'; var pattern = /one/g; var result = text.match(pattern); // one,one What are regular expression patterns Regular Expressions provide a group of patterns in order to match characters. Basically they are categorized into 3 types, Brackets: These are used to find a range of characters. For example, below are some use cases,[abc]: Used to find any of the characters between the brackets(a,b,c)[0-9]: Used to find any of the digits between the brackets(a|b): Used to find any of the alternatives separated with | Metacharacters: These are characters with a special meaning For example, below are some use cases,\d: Used to find a digit\s: Used to find a whitespace character\b: Used to find a match at the beginning or ending of a word Quantifiers: These are useful to define quantities For example, below are some use cases, n+: Used to find matches for any string that contains at least one n n*: Used to find matches for any string that contains zero or more occurrences of n n?: Used to find matches for any string that contains zero or one occurrences of n What is a RegExp object RegExp object is a regular expression object with predefined properties and methods. Let's see the simple usage of RegExp object, var regexp = new RegExp('\\w+'); console.log(regexp); // expected output: /\w+/ How do you search a string for a pattern You can use the test() method of regular expression in order to search a string for a pattern, and return true or false depending on the result. var pattern = /you/; console.log(pattern.test('How are you?')); //true What is the purpose of exec method The purpose of exec method is similar to test method but it executes a search for a match in a specified string and returns a result array, or null instead of returning true/false. var pattern = /you/; console.log(pattern.exec('How are you?')); //["you", index: 8, input: "How are you?", groups: undefined] How do you change the style of a HTML element You can change inline style or classname of a HTML element using javascript Using style property: You can modify inline style using style property document.getElementById('title').style.fontSize = '30px'; Using ClassName property: It is easy to modify element class using className property document.getElementById('title').className = 'custom-title'; What would be the result of 1+2+'3' The output is going to be 33. Since 1 and 2 are numeric values, the result of the first two digits is going to be a numeric value 3. The next digit is a string type value because of that the addition of numeric value 3 and string type value 3 is just going to be a concatenation value 33. What is a debugger statement The debugger statement invokes any available debugging functionality, such as setting a breakpoint. If no debugging functionality is available, this statement has no effect. For example, in the below function a debugger statement has been inserted. So execution is paused at the debugger statement just like a breakpoint in the script source. function getProfile() { // code goes here debugger; // code goes here } What is the purpose of breakpoints in debugging You can set breakpoints in the javascript code once the debugger statement is executed and the debugger window pops up. At each breakpoint, javascript will stop executing, and let you examine the JavaScript values. After examining values, you can resume the execution of code using the play button. Can I use reserved words as identifiers No, you cannot use the reserved words as variables, labels, object or function names. Let's see one simple example, var else = "hello"; // Uncaught SyntaxError: Unexpected token else How do you detect a mobile browser You can use regex which returns a true or false value depending on whether or not the user is browsing with a mobile. window.mobilecheck = function () { var mobileCheck = false; (function (a) { if ( /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test( a ) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test( a.substr(0, 4) ) ) mobileCheck = true; })(navigator.userAgent || navigator.vendor || window.opera); return mobileCheck; }; How do you detect a mobile browser without regexp You can detect mobile browsers by simply running through a list of devices and checking if the useragent matches anything. This is an alternative solution for RegExp usage, function detectmob() { if ( navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/webOS/i) || navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/BlackBerry/i) || navigator.userAgent.match(/Windows Phone/i) ) { return true; } else { return false; } } How do you get the image width and height using JS You can programmatically get the image and check the dimensions(width and height) using Javascript. var img = new Image(); img.onload = function () { console.log(this.width + 'x' + this.height); }; img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif'; How do you make synchronous HTTP request Browsers provide an XMLHttpRequest object which can be used to make synchronous HTTP requests from JavaScript function httpGet(theUrl) { var xmlHttpReq = new XMLHttpRequest(); xmlHttpReq.open('GET', theUrl, false); // false for synchronous request xmlHttpReq.send(null); return xmlHttpReq.responseText; } How do you make asynchronous HTTP request Browsers provide an XMLHttpRequest object which can be used to make asynchronous HTTP requests from JavaScript by passing the 3rd parameter as true. function httpGetAsync(theUrl, callback) { var xmlHttpReq = new XMLHttpRequest(); xmlHttpReq.onreadystatechange = function () { if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) callback(xmlHttpReq.responseText); }; xmlHttp.open('GET', theUrl, true); // true for asynchronous xmlHttp.send(null); } How do you convert date to another timezone in javascript You can use the toLocaleString() method to convert dates in one timezone to another. For example, let's convert current date to British English timezone as below, console.log(event.toLocaleString('en-GB', { timeZone: 'UTC' })); //29/06/2019, 09:56:00 What are the properties used to get size of window You can use innerWidth, innerHeight, clientWidth, clientHeight properties of windows, document element and document body objects to find the size of a window. Let's use them combination of these properties to calculate the size of a window or document, var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; What is a conditional operator in javascript The conditional (ternary) operator is the only JavaScript operator that takes three operands which acts as a shortcut for if statements. var isAuthenticated = false; console.log(isAuthenticated ? 'Hello, welcome' : 'Sorry, you are not authenticated'); //Sorry, you are not authenticated Can you apply chaining on conditional operator Yes, you can apply chaining on conditional operators similar to if … else if … else if … else chain. The syntax is going to be as below, function traceValue(someParam) { return condition1 ? value1 : condition2 ? value2 : condition3 ? value3 : value4; } // The above conditional operator is equivalent to: function traceValue(someParam) { if (condition1) { return value1; } else if (condition2) { return value2; } else if (condition3) { return value3; } else { return value4; } } What are the ways to execute javascript after page load You can execute javascript after page load in many different ways, window.onload: window.onload = function ... document.onload: document.onload = function ... body onload:<body onload="script();"> What is the difference between proto and prototype The __proto__ object is the actual object that is used in the lookup chain to resolve methods, etc. Whereas prototype is the object that is used to build __proto__ when you create an object with new new Employee().__proto__ === Employee.prototype; new Employee().prototype === undefined; Give an example where do you really need semicolon It is recommended to use semicolons after every statement in JavaScript. For example, in the below case it throws an error ".. is not a function" at runtime due to missing semicolon.// define a function var fn = (function () { //... })( // semicolon missing at this line // then execute some code inside a closure function () { //... } )(); and it will be interpreted as var fn = (function () { //... })(function () { //... })(); In this case, we are passing the second function as an argument to the first function and then trying to call the result of the first function call as a function. Hence, the second function will fail with a "... is not a function" error at runtime. What is a freeze method The freeze() method is used to freeze an object. Freezing an object does not allow adding new properties to an object,prevents from removing and prevents changing the enumerability, configurability, or writability of existing properties. i.e, It returns the passed object and does not create a frozen copy. const obj = { prop: 100 }; Object.freeze(obj); obj.prop = 200; // Throws an error in strict mode console.log(obj.prop); //100 Note: It causes a TypeError if the argument passed is not an object. What is the purpose of freeze method Below are the main benefits of using freeze method, It is used for freezing objects and arrays. It is used to make an object immutable. Why do I need to use freeze method In the Object-oriented paradigm, an existing API contains certain elements that are not intended to be extended, modified, or re-used outside of their current context. Hence it works as the final keyword which is used in various languages. How do you detect a browser language preference You can use navigator object to detect a browser language preference as below, var language = (navigator.languages && navigator.languages[0]) || // Chrome / Firefox navigator.language || // All browsers navigator.userLanguage; // IE <= 10 console.log(language); How to convert string to title case with javascript Title case means that the first letter of each word is capitalized. You can convert a string to title case using the below function, function toTitleCase(str) { return str.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }); } toTitleCase('good morning john'); // Good Morning John How do you detect javascript disabled in the page You can use the <noscript> tag to detect javascript disabled or not. The code block inside <noscript> gets executed when JavaScript is disabled, and is typically used to display alternative content when the page generated in JavaScript.<script type="javascript"> // JS related code goes here </script> <noscript> <a href="next_page.html?noJS=true">JavaScript is disabled in the page. Please click Next Page</a> </noscript> What are various operators supported by javascript An operator is capable of manipulating(mathematical and logical computations) a certain value or operand. There are various operators supported by JavaScript as below, Arithmetic Operators: Includes + (Addition),– (Subtraction), * (Multiplication), / (Division), % (Modulus), + + (Increment) and – – (Decrement) Comparison Operators: Includes = =(Equal),!= (Not Equal), ===(Equal with type), > (Greater than),> = (Greater than or Equal to),< (Less than),<= (Less than or Equal to) Logical Operators: Includes &&(Logical AND),||(Logical OR),!(Logical NOT) Assignment Operators: Includes = (Assignment Operator), += (Add and Assignment Operator), – = (Subtract and Assignment Operator), *= (Multiply and Assignment), /= (Divide and Assignment), %= (Modules and Assignment) Ternary Operators: It includes conditional(: ?) Operator typeof Operator: It uses to find type of variable. The syntax looks like typeof variable What is a rest parameter Rest parameter is an improved way to handle function parameters which allows us to represent an indefinite number of arguments as an array. The syntax would be as below, function f(a, b, ...theArgs) { // ... } For example, let's take a sum example to calculate on dynamic number of parameters, function total(…args){ let sum = 0; for(let i of args){ sum+=i; } return sum; } console.log(fun(1,2)); //3 console.log(fun(1,2,3)); //6 console.log(fun(1,2,3,4)); //13 console.log(fun(1,2,3,4,5)); //15 Note: Rest parameter is added in ES2015 or ES6 What happens if you do not use rest parameter as a last argument The rest parameter should be the last argument, as its job is to collect all the remaining arguments into an array. For example, if you define a function like below it doesn't make any sense and will throw an error. function someFunc(a,…b,c){ //You code goes here return; } What are the bitwise operators available in javascript Below are the list of bitwise logical operators used in JavaScript Bitwise AND ( & ) Bitwise OR ( | ) Bitwise XOR ( ^ ) Bitwise NOT ( ~ ) Left Shift ( << ) Sign Propagating Right Shift ( >> ) Zero fill Right Shift ( >>> ) What is a spread operator Spread operator allows iterables( arrays / objects / strings ) to be expanded into single arguments/elements. Let's take an example to see this behavior, function calculateSum(x, y, z) { return x + y + z; } const numbers = [1, 2, 3]; console.log(calculateSum(...numbers)); // 6 How do you determine whether object is frozen or not Object.isFrozen() method is used to determine if an object is frozen or not.An object is frozen if all of the below conditions hold true, If it is not extensible. If all of its properties are non-configurable. If all its data properties are non-writable. The usage is going to be as follows, const object = { property: 'Welcome JS world' }; Object.freeze(object); console.log(Object.isFrozen(object)); How do you determine two values same or not using object The Object.is() method determines whether two values are the same value. For example, the usage with different types of values would be, Object.is('hello', 'hello'); // true Object.is(window, window); // true Object.is([], []); // false Two values are the same if one of the following holds: both undefined both null both true or both false both strings of the same length with the same characters in the same order both the same object (means both object have same reference) both numbers and both +0 both -0 both NaN both non-zero and both not NaN and both have the same value. What is the purpose of using object is method Some of the applications of Object's is method are follows, It is used for comparison of two strings. It is used for comparison of two numbers. It is used for comparing the polarity of two numbers. It is used for comparison of two objects. How do you copy properties from one object to other You can use the Object.assign() method which is used to copy the values and properties from one or more source objects to a target object. It returns the target object which has properties and values copied from the target object. The syntax would be as below, Object.assign(target, ...sources); Let's take example with one source and one target object, const target = { a: 1, b: 2 }; const source = { b: 3, c: 4 }; const returnedTarget = Object.assign(target, source); console.log(target); // { a: 1, b: 3, c: 4 } console.log(returnedTarget); // { a: 1, b: 3, c: 4 } As observed in the above code, there is a common property( b) from source to target so it's value has been overwritten. What are the applications of assign method Below are the some of main applications of Object.assign() method, It is used for cloning an object. It is used to merge objects with the same properties. What is a proxy object The Proxy object is used to define custom behavior for fundamental operations such as property lookup, assignment, enumeration, function invocation, etc. The syntax would be as follows, var p = new Proxy(target, handler); Let's take an example of proxy object, var handler = { get: function (obj, prop) { return prop in obj ? obj[prop] : 100; } }; var p = new Proxy({}, handler); p.a = 10; p.b = null; console.log(p.a, p.b); // 10, null console.log('c' in p, p.c); // false, 100 In the above code, it uses get handler which define the behavior of the proxy when an operation is performed on it What is the purpose of seal method The Object.seal() method is used to seal an object, by preventing new properties from being added to it and marking all existing properties as non-configurable. But values of present properties can still be changed as long as they are writable. Let's see the below example to understand more about seal() method const object = { property: 'Welcome JS world' }; Object.seal(object); object.property = 'Welcome to object world'; console.log(Object.isSealed(object)); // true delete object.property; // You cannot delete when sealed console.log(object.property); //Welcome to object world What are the applications of seal method Below are the main applications of Object.seal() method, It is used for sealing objects and arrays. It is used to make an object immutable. What are the differences between freeze and seal methods If an object is frozen using the Object.freeze() method then its properties become immutable and no changes can be made in them whereas if an object is sealed using the Object.seal() method then the changes can be made in the existing properties of the object. How do you determine if an object is sealed or not The Object.isSealed() method is used to determine if an object is sealed or not. An object is sealed if all of the below conditions hold true If it is not extensible. If all of its properties are non-configurable. If it is not removable (but not necessarily non-writable). Let's see it in the action const object = { property: 'Hello, Good morning' }; Object.seal(object); // Using seal() method to seal the object console.log(Object.isSealed(object)); // checking whether the object is sealed or not How do you get enumerable key and value pairs The Object.entries() method is used to return an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop. Let's see the functionality of object.entries() method in an example, const object = { a: 'Good morning', b: 100 }; for (let [key, value] of Object.entries(object)) { console.log(`${key}: ${value}`); // a: 'Good morning' // b: 100 } Note: The order is not guaranteed as object defined. What is the main difference between Object.values and Object.entries method The Object.values() method's behavior is similar to Object.entries() method but it returns an array of values instead [key,value] pairs. const object = { a: 'Good morning', b: 100 }; for (let value of Object.values(object)) { console.log(`${value}`); // 'Good morning' 100; } How can you get the list of keys of any object You can use the Object.keys() method which is used to return an array of a given object's own property names, in the same order as we get with a normal loop. For example, you can get the keys of a user object, const user = { name: 'John', gender: 'male', age: 40 }; console.log(Object.keys(user)); //['name', 'gender', 'age'] How do you create an object with prototype The Object.create() method is used to create a new object with the specified prototype object and properties. i.e, It uses an existing object as the prototype of the newly created object. It returns a new object with the specified prototype object and properties. const user = { name: 'John', printInfo: function () { console.log(`My name is ${this.name}.`); } }; const admin = Object.create(user); admin.name = 'Nick'; // Remember that "name" is a property set on "admin" but not on "user" object admin.printInfo(); // My name is Nick What is a WeakSet WeakSet is used to store a collection of weakly(weak references) held objects. The syntax would be as follows, new WeakSet([iterable]); Let's see the below example to explain it's behavior, var ws = new WeakSet(); var user = {}; ws.add(user); ws.has(user); // true ws.delete(user); // removes user from the set ws.has(user); // false, user has been removed What are the differences between WeakSet and Set The main difference is that references to objects in Set are strong while references to objects in WeakSet are weak. i.e, An object in WeakSet can be garbage collected if there is no other reference to it. Other differences are, Sets can store any value Whereas WeakSets can store only collections of objects WeakSet does not have size property unlike Set WeakSet does not have methods such as clear, keys, values, entries, forEach. WeakSet is not iterable. List down the collection of methods available on WeakSet Below are the list of methods available on WeakSet, add(value): A new object is appended with the given value to the weakset delete(value): Deletes the value from the WeakSet collection. has(value): It returns true if the value is present in the WeakSet Collection, otherwise it returns false. Let's see the functionality of all the above methods in an example, var weakSetObject = new WeakSet(); var firstObject = {}; var secondObject = {}; // add(value) weakSetObject.add(firstObject); weakSetObject.add(secondObject); console.log(weakSetObject.has(firstObject)); //true weakSetObject.delete(secondObject); What is a WeakMap The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced. In this case, keys must be objects and the values can be arbitrary values. The syntax is looking like as below, new WeakMap([iterable]); Let's see the below example to explain it's behavior, var ws = new WeakMap(); var user = {}; ws.set(user); ws.has(user); // true ws.delete(user); // removes user from the map ws.has(user); // false, user has been removed What are the differences between WeakMap and Map The main difference is that references to key objects in Map are strong while references to key objects in WeakMap are weak. i.e, A key object in WeakMap can be garbage collected if there is no other reference to it. Other differences are, Maps can store any key type Whereas WeakMaps can store only collections of key objects WeakMap does not have size property unlike Map WeakMap does not have methods such as clear, keys, values, entries, forEach. WeakMap is not iterable. List down the collection of methods available on WeakMap Below are the list of methods available on WeakMap, set(key, value): Sets the value for the key in the WeakMap object. Returns the WeakMap object. delete(key): Removes any value associated to the key. has(key): Returns a Boolean asserting whether a value has been associated to the key in the WeakMap object or not. get(key): Returns the value associated to the key, or undefined if there is none. Let's see the functionality of all the above methods in an example, var weakMapObject = new WeakMap(); var firstObject = {}; var secondObject = {}; // set(key, value) weakMapObject.set(firstObject, 'John'); weakMapObject.set(secondObject, 100); console.log(weakMapObject.has(firstObject)); //true console.log(weakMapObject.get(firstObject)); // John weakMapObject.delete(secondObject); What is the purpose of uneval The uneval() is an inbuilt function which is used to create a string representation of the source code of an Object. It is a top-level function and is not associated with any object. Let's see the below example to know more about it's functionality, var a = 1; uneval(a); // returns a String containing 1 uneval(function user() {}); // returns "(function user(){})" How do you encode an URL The encodeURI() function is used to encode complete URI which has special characters except (, / ? : @ & = + $ #) characters. var uri = 'https://mozilla.org/?x=шеллы'; var encoded = encodeURI(uri); console.log(encoded); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B How do you decode an URL The decodeURI() function is used to decode a Uniform Resource Identifier (URI) previously created by encodeURI(). var uri = 'https://mozilla.org/?x=шеллы'; var encoded = encodeURI(uri); console.log(encoded); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B try { console.log(decodeURI(encoded)); // "https://mozilla.org/?x=шеллы" } catch (e) { // catches a malformed URI console.error(e); } How do you print the contents of web page The window object provided a print() method which is used to print the contents of the current window. It opens a Print dialog box which lets you choose between various printing options. Let's see the usage of print method in an example,<input type="button" value="Print" onclick="window.print()" /> Note: In most browsers, it will block while the print dialog is open. What is the difference between uneval and eval The uneval function returns the source of a given object; whereas the eval function does the opposite, by evaluating that source code in a different memory area. Let's see an example to clarify the difference, var msg = uneval(function greeting() { return 'Hello, Good morning'; }); var greeting = eval(msg); greeting(); // returns "Hello, Good morning" What is an anonymous function An anonymous function is a function without a name! Anonymous functions are commonly assigned to a variable name or used as a callback function. The syntax would be as below, function (optionalParameters) { //do something } const myFunction = function(){ //Anonymous function assigned to a variable //do something }; [1, 2, 3].map(function(element){ //Anonymous function used as a callback function //do something }); Let's see the above anonymous function in an example, var x = function (a, b) { return a * b; }; var z = x(5, 10); console.log(z); // 50 What is the precedence order between local and global variables A local variable takes precedence over a global variable with the same name. Let's see this behavior in an example.
    https://bgoonz-blog.netlify.app/images/code-299f1fc7.png
  • Web-Dev-Hub
    September 02, 2021 Git Bash understanding git bsh Understanding Git Bash Git Bash At its core, Git is a set of command line utility programs that are designed to execute on a Unix style command-line environment. Modern operating systems like Linux and macOS both include built-in Unix command line terminals. This makes Linux and macOS complementary operating systems when working with Git. Microsoft Windows instead uses Windows command prompt, a non-Unix terminal environment. In Windows environments, Git is often packaged as part of higher level GUI applications. GUIs for Git may attempt to abstract and hide the underlying version control system primitives. This can be a great aid for Git beginners to rapidly contribute to a project. Once a project's collaboration requirements grow with other team members, it is critical to be aware of how the actual raw Git methods work. This is when it can be beneficial to drop a GUI version for the command line tools. Git Bash is offered to provide a terminal Git experience. What is Git Bash? Git Bash is an application for Microsoft Windows environments which provides an emulation layer for a Git command line experience. Bash is an acronym for Bourne Again Shell. A shell is a terminal application used to interface with an operating system through written commands. Bash is a popular default shell on Linux and macOS. Git Bash is a package that installs Bash, some common bash utilities, and Git on a Windows operating system. How to install Git Bash Git Bash comes included as part of the Git For Windows package. Download and install Git For Windows like other Windows applications. Once downloaded find the included .exe file and open to execute Git Bash. How to use Git Bash Git Bash has the same operations as a standard Bash experience. It will be helpful to review basic Bash usage. Advanced usage of Bash is outside the scope of this Git focused document. How to navigate folders The Bash command pwd is used to print the 'present working directory'. pwd is equivalent to executing cd on a DOS(Windows console host) terminal. This is the folder or path that the current Bash session resides in. The Bash command ls is used to 'list' contents of the current working directory. ls is equivalent to DIR on a Windows console host terminal. Both Bash and Windows console host have a cd command. cd is an acronym for 'Change Directory'. cd is invoked with an appended directory name. Executing cd will change the terminal sessions current working directory to the passed directory argument. Git Bash Commands Git Bash is packaged with additional commands that can be found in the /usr/bin directory of the Git Bash emulation. Git Bash can actually provide a fairly robust shell experience on Windows. Git Bash comes packaged with the following shell commands which are outside the scope of this document: [Ssh](https://man.openbsd.org/ssh.1), [scp](https://linux.die.net/man/1/scp), [cat](http://man7.org/linux/man-pages/man1/cat.1.html), [find](https://linux.die.net/man/1/find). In addition the previously discussed set of Bash commands, Git Bash includes the full set of Git core commands discussed through out this site. Learn more at the corresponding documentation pages for
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    October 14, 2021 Functions in Python Functions in Python Functions def hello(name): print('Hello {}'.format(name)) Return Values and return Statements When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following: The return keyword. The value or expression that the function should return. import random def getAnswer(answerNumber): if answerNumber == 1: return 'It is certain' elif answerNumber == 2: return 'It is decidedly so' elif answerNumber == 3: return 'Yes' elif answerNumber == 4: return 'Reply hazy try again' elif answerNumber == 5: return 'Ask again later' elif answerNumber == 6: return 'Concentrate and ask again' elif answerNumber == 7: return 'My reply is no' elif answerNumber == 8: return 'Outlook not so good' elif answerNumber == 9: return 'Very doubtful' r = random.randint(1, 9) fortune = getAnswer(r) print(fortune) The None Value spam = print('Hello!') spam is None Note: never compare to None with the == operator. Always use is. print Keyword Arguments print('Hello', end='') print('World') print('cats', 'dogs', 'mice') print('cats', 'dogs', 'mice', sep=',') Local and Global Scope Code in the global scope cannot use any local variables. However, a local scope can access global variables. Code in a function's local scope cannot use variables in any other local scope. You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam. The global Statement If you need to modify a global variable from within a function, use the global statement: def spam(): global eggs eggs = 'spam' eggs = 'global' spam() print(eggs) There are four rules to tell whether a variable is in a local scope or global scope: If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable. If there is a global statement for that variable in a function, it is a global variable. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable. But if the variable is not used in an assignment statement, it is a global variable.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    October 14, 2021 flow-control-in-python flow-control-in-python Read It Website Github PDF Jupyter Notebook Flow Control Comparison Operators Operator Meaning== Equal to!= Not equal to< Less than> Greater Than<= Less than or Equal to>= Greater than or Equal to These operators evaluate to True or False depending on the values you give them. Examples: 42 == 42 40 == 42 'hello' == 'hello' 'hello' == 'Hello' 'dog' != 'cat' 42 == 42.0 42 == '42' Boolean evaluation Never use == or != operator to evaluate boolean operation. Use the is or is not operators, or use implicit boolean evaluation. NO (even if they are valid Python): True == True True != False YES (even if they are valid Python): True is True True is not False These statements are equivalent: if a is True: pass if a is not False: pass if a: pass And these as well: if a is False: pass if a is not True: pass if not a: pass Boolean Operators There are three Boolean operators: and, or, and not. The and Operator's Truth Table: Expression Evaluates to True and True True True and False False False and True False False and False False The or Operator's Truth Table: Expression Evaluates to True or True True True or False True False or True True False or False False The not Operator's Truth Table: Expression Evaluates to not True False not False True Mixing Boolean and Comparison Operators(4 < 5) and (5 < 6) (4 < 5) and (9 < 6) (1 == 2) or (2 == 2) You can also use multiple Boolean operators in an expression, along with the comparison operators: 2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2 if Statements if name == 'Alice': print('Hi, Alice.') else Statements name = 'Bob' if name == 'Alice': print('Hi, Alice.') else: print('Hello, stranger.') elif Statements name = 'Bob' age = 5 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') name = 'Bob' age = 30 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') else: print('You are neither Alice nor a little kid.') while Loop Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 break Statements If the execution reaches a break statement, it immediately exits the while loop's clause: while True: print('Please type your name.') name = input() if name == 'your name': break print('Thank you!') continue Statements When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop. while True: print('Who are you?') name = input() if name != 'Joe': continue print('Hello, Joe. What is the password? (It is a fish.)') password = input() if password == 'swordfish': break print('Access granted.') for Loops and the range() Function print('My name is') for i in range(5): print('Jimmy Five Times ({})'.format(str(i))) The range() function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration. for i in range(0, 10, 2): print(i) You can even use a negative number for the step argument to make the for loop count down instead of up. for i in range(5, -1, -1): print(i) For else statement This allows you to specify a statement to execute after the full loop has been executed. Only useful when a break condition can occur in the loop: for i in [1, 2, 3, 4, 5]: if i == 3: break else: print("only executed when no item of the list is equal to 3") Importing Modules import random for i in range(5): print(random.randint(1, 10)) import random, sys, os, math from random import * Ending a Program with sys.exit import sys while True: print('Type exit to exit.') response = input() if response == 'exit': sys.exit() print('You typed {}.'.format(response))
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    September 14, 2021 Leetcode (Data Structures) practice Leetcode Data Structures & Algorithms DS Algo Codebase➤ 115. Distinct Subsequences Problem: Given a string S and a string T, count the number of distinct subsequences of S which equals T. A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). Example 1: Input: S = "rabbbit", T = "rabbit" Output: 3 Explanation: As shown below, there are 3 ways you can generate "rabbit" from S. (The caret symbol ^ means the chosen letters) rabbbit ^^^^ ^^ rabbbit ^^ ^^^^ rabbbit ^^^ ^^^ Example 2: Input: S = "babgbag", T = "bag" Output: 5 Explanation: As shown below, there are 5 ways you can generate "bag" from S. (The caret symbol ^ means the chosen letters) babgbag ^^ ^ babgbag ^^ ^ babgbag ^ ^^ babgbag ^ ^^ babgbag ^^^ Solution: Define f(i, j) to be the number of ways that generate T[0...j) from S[0...i). For f(i, j) you can always skip S[i-1], but can only take it when S[i-1] === T[j-1]. f(0, j) = 0, j > 0 // nothing to delete f(i, 0) = 1 // delete all f(i, j) = f(i-1, j) + (S[i-1] === T[j-1] ? f(i-1, j-1) : 0) Dynamic array can be used./** * @param {string} s * @param {string} t * @return {number} */ let numDistinct = function (s, t) { const lens = s.length; const lent = t.length; const dp = new Array(lent + 1).fill(0); dp[0] = 1; for (let i = 1; i <= lens; i++) { for (let j = lent; j >= 1; j--) { if (s[i - 1] === t[j - 1]) { dp[j] += dp[j - 1]; } } } return dp[lent]; }; Difficulty: Medium Related Topics: "Tree": https://leetcode.com/tag/tree "Depth-first Search": https://leetcode.com/tag/depth-first-search Similar Questions: "Populating Next Right Pointers in Each Node II": https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii "Binary Tree Right Side View": https://leetcode.com/problems/binary-tree-right-side-view➤ 116. Populating Next Right Pointers in Each Node Problem: Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Note: You may only use constant extra space. Recursive approach is fine, implicit stack space does not count as extra space for this problem. You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). Example: Given the following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL Solution: ONE Recursive. For every node: Left child: points to node.right. Right child: points to node.next.left if node.next exists./** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ let connect = function (root) { if (!root) { return; } if (root.left !== null) { root.left.next = root.right; connect(root.left); } if (root.right !== null) { if (root.next !== null) { root.right.next = root.next.left; } connect(root.right); } }; TWO Level order traversal./** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ let connect = function (root) { if (!root) { return; } const queue = [NaN, root]; while (queue.length > 1) { const node = queue.shift(); if (node !== node) { for (let i = 0; i < queue.length; i++) { queue[i].next = queue[i + 1] || null; } queue.push(NaN); } else { if (node.left !== null) { queue.push(node.left); } if (node.right !== null) { queue.push(node.right); } } } }; Difficulty: Medium Related Topics: "Tree": https://leetcode.com/tag/tree "Depth-first Search": https://leetcode.com/tag/depth-first-search Similar Questions: "Populating Next Right Pointers in Each Node": https://leetcode.com/problems/populating-next-right-pointers-in-each-node➤ 117. Populating Next Right Pointers in Each Node II Problem: Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Note: You may only use constant extra space. Recursive approach is fine, implicit stack space does not count as extra space for this problem. Example: Given the following binary tree, 1 / \ 2 3 / \ \ 4 5 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ \ 4-> 5 -> 7 -> NULL Solution: ONE Recursive. See 116. Populating Next Right Pointers in Each Node. The tree may not be perfect now. So keep finding next until there is a node with children, or null. This also means post-order traversal is required./** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ let connect = function (root) { if (!root) { return; } let next = null; for (let node = root.next; node !== null; node = node.next) { if (node.left !== null) { next = node.left; break; } if (node.right !== null) { next = node.right; break; } } if (root.right !== null) { root.right.next = next; } if (root.left !== null) { root.left.next = root.right || next; } connect(root.right); connect(root.left); }; TWO Level order traversal. Exact same as 116. Populating Next Right Pointers in Each Node./** * Definition for binary tree with next pointer. * function TreeLinkNode(val) { * this.val = val; * this.left = this.right = this.next = null; * } */ /** * @param {TreeLinkNode} root * @return {void} Do not return anything, modify tree in-place instead. */ let connect = function (root) { if (!root) { return; } const queue = [NaN, root]; while (queue.length > 1) { const node = queue.shift(); if (node !== node) { for (let i = 0; i < queue.length; i++) { queue[i].next = queue[i + 1] || null; } queue.push(NaN); } else { if (node.left !== null) { queue.push(node.left); } if (node.right !== null) { queue.push(node.right); } } } }; Difficulty: Easy Related Topics: "Array": https://leetcode.com/tag/array Similar Questions: "Pascal's Triangle II": https://leetcode.com/problems/pascals-triangle-ii➤ 118. Pascal's Triangle Problem: Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. In Pascal's triangle, each number is the sum of the two numbers directly above it. Example: Input: 5 Output: [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] Solution: Dynamic Programming 101./** * @param {number} numRows * @return {number[][]} */ let generate = function (numRows) { if (numRows <= 0) { return []; } const result = [[1]]; for (let i = 1; i < numRows; i++) { const lastRow = result[i - 1]; const row = [1]; for (let j = 1; j < i; j++) { row[j] = lastRow[j] + lastRow[j - 1]; } row.push(1); result.push(row); } return result; }; Difficulty: Easy Related Topics: "Array": https://leetcode.com/tag/array Similar Questions: "Pascal's Triangle": https://leetcode.com/problems/pascals-triangle➤ 119. Pascal's Triangle II Problem: Given a non-negative index k where k ≤ 33, return the k th index row of the Pascal's triangle. Note that the row index starts from 0. In Pascal's triangle, each number is the sum of the two numbers directly above it. Example: Input: 3 Output: [1,3,3,1] Follow up: Could you optimize your algorithm to use only O( k) extra space? Solution: Dynamic Programming 101 with dynamic array. State (i, j) depends on (i-1, j) and (i-1, j-1). So to access (i-1, j-1) iteration must be from right to left./** * @param {number} rowIndex * @return {number[]} */ let getRow = function (rowIndex) { if (rowIndex < 0) { return []; } const row = [1]; for (let i = 1; i <= rowIndex; i++) { for (let j = i - 1; j > 0; j--) { row[j] += row[j - 1]; } row.push(1); } return row; }; Difficulty: Medium Related Topics: "Array": https://leetcode.com/tag/array "Dynamic Programming": https://leetcode.com/tag/dynamic-programming➤ 120. Triangle Problem: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle[ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). Note: Bonus point if you are able to do this using only O( n) extra space, where n is the total number of rows in the triangle. Solution: Define f(i, j) to be the minimum path sum from triangle[0][0] to triangle[i][j]. f(i, 0) = f(i-1, j) + triangle[i][0] f(i, j) = min( f(i-1, j-1), f(i-1, j) ) + triangle[i][j], 0 < j < i f(i, i) = f(i-1, i-1) + triangle[i][i], i > 0 Dynamic array can be used./** * @param {number[][]} triangle * @return {number} */ let minimumTotal = function (triangle) { if (triangle.length <= 0) { return 0; } const dp = [triangle[0][0]]; for (let i = 1; i < triangle.length; i++) { dp[i] = dp[i - 1] + triangle[i][i]; for (let j = i - 1; j >= 1; j--) { dp[j] = Math.min(dp[j], dp[j - 1]) + triangle[i][j]; } dp[0] += triangle[i][0]; } return Math.min(...dp); }; Difficulty: Easy Related Topics: "Array": https://leetcode.com/tag/array "Dynamic Programming": https://leetcode.com/tag/dynamic-programming Similar Questions: "Maximum Subarray": https://leetcode.com/problems/maximum-subarray "Best Time to Buy and Sell Stock II": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii "Best Time to Buy and Sell Stock III": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii "Best Time to Buy and Sell Stock IV": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv "Best Time to Buy and Sell Stock with Cooldown": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown➤ 121. Best Time to Buy and Sell Stock Problem: Say you have an array for which the i th element is the price of a given stock on day i. If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. Note that you cannot sell a stock before you buy one. Example 1: Input: [7,1,5,3,6,4] Output: 5 Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Not 7-1 = 6, as selling price needs to be larger than buying price. Example 2: Input: [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0. Solution: Only care about positive profits. Take the frist item as base and scan to the right. If we encounter an item j whose price price[j] is lower than the base (which means if we sell now the profit would be negative), we sell j-1 instead and make j the new base. Because price[j] is lower that the base, using j as new base is guaranteed to gain more profit comparing to the old one./** * @param {number[]} prices * @return {number} */ let maxProfit = function (prices) { let max = 0; let base = prices[0]; for (let i = 1; i < prices.length; i++) { const profit = prices[i] - base; if (profit > max) { max = profit; } else if (profit < 0) { base = prices[i]; } } return max; }; Difficulty: Easy Related Topics: "Array": https://leetcode.com/tag/array "Greedy": https://leetcode.com/tag/greedy Similar Questions: "Best Time to Buy and Sell Stock": https://leetcode.com/problems/best-time-to-buy-and-sell-stock "Best Time to Buy and Sell Stock III": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii "Best Time to Buy and Sell Stock IV": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv "Best Time to Buy and Sell Stock with Cooldown": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown "Best Time to Buy and Sell Stock with Transaction Fee": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee➤ 122. Best Time to Buy and Sell Stock II Problem: Say you have an array for which the i th element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). Example 1: Input: [7,1,5,3,6,4] Output: 7 Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. Example 2: Input: [1,2,3,4,5] Output: 4 Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again. Example 3: Input: [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0. Solution: Sell immediately after the price drops. Or in other perspective, it is the sum of all the incremental pairs (buy in then immediately sell out)./** * @param {number[]} prices * @return {number} */ let maxProfit = function (prices) { let max = 0; for (let i = 1; i < prices.length; i++) { if (prices[i] > prices[i - 1]) { max += prices[i] - prices[i - 1]; } } return max; }; Difficulty: Hard Related Topics: "Array": https://leetcode.com/tag/array "Dynamic Programming": https://leetcode.com/tag/dynamic-programming Similar Questions: "Best Time to Buy and Sell Stock": https://leetcode.com/problems/best-time-to-buy-and-sell-stock "Best Time to Buy and Sell Stock II": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii "Best Time to Buy and Sell Stock IV": https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv "Maximum Sum of 3 Non-Overlapping Subarrays": https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays➤ 123. Best Time to Buy and Sell Stock III Problem: Say you have an array for which the i th element is the price of a given stock on day i. Design an algorithm to find the maximum profit. You may complete at most two transactions.**Note:**You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). Example 1: Input: [3,3,5,0,0,3,1,4] Output: 6 Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3. Example 2: Input: [1,2,3,4,5] Output: 4 Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are engaging multiple transactions at the same time. You must sell before buying again. Example 3: Input: [7,6,4,3,1] Output: 0 Explanation: In this case, no transaction is done, i.e. max profit = 0. Solution: Multiple transactions may not be engaged in at the same time. That means if we view the days that involed in the same transaction as a group, there won't be any intersection. We may complete at most two transactions, so divide the days into two groups, [0...k] and [k...n-1]. Notice k exists in both groups because technically we can sell out then immediately buy in at the same day. Define p1(i) to be the max profit of day [0...i]. This is just like the problem of 121. Best Time to Buy and Sell Stock. p1(0) = 0 p1(i) = max( p1(i-1), prices[i] - min(prices[0], ..., prices[i-1]) ), 0 < i <= n-1 Define p2(i) to be the max profit of day [i...n-1]. This is the mirror of p1. p2(n-1) = 0 p2(i) = max( p2(i+1), max(prices[i], ..., prices[n-1]) - prices[i] ), n-1 > i >= 0 Define f(k) to be p1(k) + p2(k). We need to get max( f(0), ..., f(n-1) )./** * @param {number[]} prices * @return {number} */ let maxProfit = function (prices) { const len = prices.length; if (len <= 1) { return 0; } const dp = [0]; let min = prices[0]; for (let i = 1; i < len; i++) { dp[i] = Math.max(dp[i - 1], prices[i] - min); min = Math.min(prices[i], min); } let p2 = 0; let max = prices[len - 1]; for (let i = len - 2; i >= 0; i--) { max = Math.max(prices[i], max); p2 = Math.max(p2, max - prices[i]); dp[i] += p2; } return Math.max(...dp); }; Difficulty: Hard Related Topics: "Tree": https://leetcode.com/tag/tree "Depth-first Search": https://leetcode.com/tag/depth-first-search Similar Questions: "Path Sum": https://leetcode.com/problems/path-sum "Sum Root to Leaf Numbers": https://leetcode.com/problems/sum-root-to-leaf-numbers "Path Sum IV": https://leetcode.com/problems/path-sum-iv "Longest Univalue Path": https://leetcode.com/problems/longest-univalue-path➤ 124. Binary Tree Maximum Path Sum Problem: Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root. Example 1: Input: [1,2,3] 1 / \ 2 3 Output: 6 Example 2: Input: [-10,9,20,null,null,15,7] -10 / \ 9 20 / \ 15 7 Output: 42 Solution: For every node, there are six possible ways to get the max path sum: With node.val node.val plus the max sum of a path that ends with node.left. node.val plus the max sum of a path that starts with node.right. node.val plus the max sum of both paths. Just node.val (the max sum of both paths are negative). Without node.val (disconnected) The max-sum path is somewhere under the node.left subtree. The max-sum path is somewhere under the node.right subtree. There are two ways to implement this. ONE Define a function that returns two values. The max sum of a path that may or may not end with root node, and the max sum of the path that ends with root node./** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ let maxPathSum = function (root) { return Math.max(..._maxPathSum(root)); }; /** * @param {TreeNode} root * @return {number[]} */ function _maxPathSum(root) { if (!root) { return [-Infinity, -Infinity]; } const left = _maxPathSum(root.left); const right = _maxPathSum(root.right); return [Math.max(left[0], right[0], root.val + Math.max(0, left[1], right[1], left[1] + right[1])), Math.max(left[1], right[1], 0) + root.val]; } TWO Just return the later (max sum of a path that ends with root). Maintain a global variable to store the disconnected max sum./** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ let maxPathSum = function (root) { const global = { max: -Infinity }; _maxPathSum(root, global); return global.max; }; /** * @param {TreeNode} root * @param {object} global * @param {number} global.max * @return {number[]} */ function _maxPathSum(root, global) { if (!root) { return -Infinity; } const left = _maxPathSum(root.left, global); const right = _maxPathSum(root.right, global); const localMax = Math.max(left, right, 0) + root.val; global.max = Math.max(global.max, localMax, root.val + left + right); return localMax; } Difficulty: Easy Related Topics: "Two Pointers": https://leetcode.com/tag/two-pointers "String": https://leetcode.com/tag/string Similar Questions: "Palindrome Linked List": https://leetcode.com/problems/palindrome-linked-list "Valid Palindrome II": https://leetcode.com/problems/valid-palindrome-ii➤ 125. Valid Palindrome Problem: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. Note: For the purpose of this problem, we define empty string as valid palindrome. Example 1: Input: "A man, a plan, a canal: Panama" Output: true Example 2: Input: "race a car" Output: false Solution: ONE/** * @param {string} s * @return {boolean} */ let isPalindrome = function (s) { const clean = s.toLowerCase().split(/[^a-z0-9]*/); return clean.join('') === clean.reverse().join(''); }; TWO Remove non-alphanumeric characters then compare./** * @param {string} s * @return {boolean} */ let isPalindrome = function (s) { const clean = s.replace(/[^a-zA-Z0-9]/g, '').toLowerCase(); for (let i = 0, j = clean.length - 1; i < j; i++, j--) { if (clean[i] !== clean[j]) { return false; } } return true; }; THREE Compare the char codes./** * @param {string} s * @return {boolean} */ let isPalindrome = function (s) { for (let i = 0, j = s.length - 1; i < j; i++, j--) { let left = s.charCodeAt(i); while (i < j && (left < 48 || (left > 57 && left < 65) || (left > 90 && left < 97) || left > 122)) { left = s.charCodeAt(++i); } if (i >= j) { return true; } if (left >= 65 && left <= 90) { left += 32; } let right = s.charCodeAt(j); while (i < j && (right < 48 || (right > 57 && right < 65) || (right > 90 && right < 97) || right > 122)) { right = s.charCodeAt(--j); } if (i >= j) { return true; } if (right >= 65 && right <= 90) { right += 32; } if (left !== right) { return false; } } return true; }; Difficulty: Hard Related Topics: "Array": https://leetcode.com/tag/array "String": https://leetcode.com/tag/string "Backtracking": https://leetcode.com/tag/backtracking "Breadth-first Search": https://leetcode.com/tag/breadth-first-search Similar Questions: "Word Ladder": https://leetcode.com/problems/word-ladder➤ 126. Word Ladder II Problem: Given two words ( beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: Only one letter can be changed at a time Each transformed word must exist in the word list. Note that beginWord is not a transformed word. Note: Return an empty list if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. You may assume no duplicates in the word list. You may assume beginWord and endWord are non-empty and are not the same. Example 1: Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ] Example 2: Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: [] Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. Solution: This is just like 127. Word Ladder. The constrain still works, but instead of deleting the words right away, collect them and delete them all when a level ends, so that we can reuse the words (matching different parents in the same level). The items in the queue are not just words now. Parent nodes are also kept so that we can backtrack the path from the end./** * @param {string} beginWord * @param {string} endWord * @param {string[]} wordList * @return {string[][]} */ function findLadders(beginWord, endWord, wordList) { wordList = new Set(wordList); if (!wordList.has(endWord)) { return []; } const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'; const result = []; let isEndWordFound = false; const levelWords = new Set(); const queue = [[beginWord, null], null]; while (queue.length > 1) { const node = queue.shift(); if (node === null) { if (isEndWordFound) { break; } levelWords.forEach((word) => wordList.delete(word)); levelWords.clear(); queue.push(null); continue; } const word = node[0]; for (let i = word.length - 1; i >= 0; i--) { const head = word.slice(0, i); const tail = word.slice(i + 1); for (let c = 0; c < 26; c++) { if (ALPHABET[c] !== word[i]) { const w = head + ALPHABET[c] + tail; if (w === endWord) { const path = [endWord]; for (let n = node; n !== null; n = n[1]) { path.unshift(n[0]); } result.push(path); isEndWordFound = true; } if (wordList.has(w)) { levelWords.add(w); queue.push([w, node]); } } } } } return result; } Difficulty: Medium Related Topics: "Breadth-first Search": https://leetcode.com/tag/breadth-first-search Similar Questions: "Word Ladder II": https://leetcode.com/problems/word-ladder-ii "Minimum Genetic Mutation": https://leetcode.com/problems/minimum-genetic-mutation➤ 127. Word Ladder Problem: Given two words ( beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: Only one letter can be changed at a time. Each transformed word must exist in the word list. Note that beginWord is not a transformed word. Note: Return 0 if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. You may assume no duplicates in the word list. You may assume beginWord and endWord are non-empty and are not the same. Example 1: Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5. Example 2: Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: 0 Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. Solution: Think of it as building a tree, with begineWord as root and endWord as leaves. The best way control the depth (length of the shortest transformations) while building the tree is level-order traversal (BFS). We do not actually build the tree because it is expensive (astronomical if the list is huge). In fact, we only need one shortest path. So just like Dijkstra's algorithm, we say that the first time (level i) we encounter a word that turns out to be in a shortest path, then level i is the lowest level this word could ever get. We can safely remove it from the wordList. To find all the next words, instead of filtering the wordList, enumerate all 25 possible words and check if in wordList./** * @param {string} beginWord * @param {string} endWord * @param {string[]} wordList * @return {number} */ let ladderLength = function (beginWord, endWord, wordList) { wordList = new Set(wordList); if (!wordList.has(endWord)) { return 0; } const ALPHABET = 'abcdefghijklmnopqrstuvwxyz'; let level = 1; const queue = [beginWord, null]; while (queue.length > 1) { const word = queue.shift(); if (word === null) { level++; queue.push(null); continue; } for (let i = word.length - 1; i >= 0; i--) { const head = word.slice(0, i); const tail = word.slice(i + 1); for (let c = 0; c < 26; c++) { if (ALPHABET[c] !== word[i]) { const word = head + ALPHABET[c] + tail; if (word === endWord) { return level + 1; } if (wordList.delete(word)) { queue.push(word); } } } } } return 0; }; Difficulty: Hard Related Topics: "Array": https://leetcode.com/tag/array "Union Find": https://leetcode.com/tag/union-find Similar Questions: "Binary Tree Longest Consecutive Sequence": https://leetcode.com/problems/binary-tree-longest-consecutive-sequence➤ 128. Longest Consecutive Sequence Problem: Given an unsorted array of integers, find the length of the longest consecutive elements sequence. Your algorithm should run in O( n) complexity. Example: Input: [100, 4, 200, 1, 3, 2] Output: 4 Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. Solution: Build a Set from the list. Pick a number, find all it's adjacent numbers that are also in the Set. Count them and remove them all from the Set. Repeat until the Set is empty. Time complexity O(n + n) = O(n)./** * @param {number[]} nums * @return {number} */ let longestConsecutive = function (nums) { const numSet = new Set(nums); let maxCount = 0; while (numSet.size > 0) { const num = numSet.values().next().value; numSet.delete(num); let count = 1; for (let n = num + 1; numSet.delete(n); n++) { count++; } for (let n = num - 1; numSet.delete(n); n--) { count++; } if (count > maxCount) { maxCount = count; } } return maxCount; }; Difficulty: Medium Related Topics: "Tree": https://leetcode.com/tag/tree "Depth-first Search": https://leetcode.com/tag/depth-first-search Similar Questions: "Path Sum": https://leetcode.com/problems/path-sum "Binary Tree Maximum Path Sum": https://leetcode.com/problems/binary-tree-maximum-path-sum➤ 129. Sum Root to Leaf Numbers Problem: Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. Note: A leaf is a node with no children. Example: Input: [1,2,3] 1 / \ 2 3 Output: 25 Explanation: The root-to-leaf path 1->2 represents the number 12. The root-to-leaf path 1->3 represents the number 13. Therefore, sum = 12 + 13 = 25. Example 2: Input: [4,9,0,5,1] 4 / \ 9 0 / \ 5 1 Output: 1026 Explanation: The root-to-leaf path 4->9->5 represents the number 495. The root-to-leaf path 4->9->1 represents the number 491. The root-to-leaf path 4->0 represents the number 40. Therefore, sum = 495 + 491 + 40 = 1026. Solution: To write a clean solution for this promblem, use 0 as indicator of leaf node. If all the children get 0, it is a leaf node, return the sum of current level./** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {number} */ let sumNumbers = function (root, sum = 0) { if (!root) { return 0; } sum = sum * 10 + root.val; return sumNumbers(root.left, sum) + sumNumbers(root.right, sum) || sum; }; Difficulty: Medium Related Topics: "Depth-first Search": https://leetcode.com/tag/depth-first-search "Breadth-first Search": https://leetcode.com/tag/breadth-first-search "Union Find": https://leetcode.com/tag/union-find Similar Questions: "Number of Islands": https://leetcode.com/problems/number-of-islands "Walls and Gates": https://leetcode.com/problems/walls-and-gates➤ 130. Surrounded Regions Problem: Given a 2D board containing 'X' and 'O' ( the letter O), capture all regions surrounded by 'X'. A region is captured by flipping all 'O' s into 'X' s in that surrounded region. Example: X X X X X O O X X X O X X O X X After running your function, the board should be: X X X X X X X X X X X X X O X X Explanation: Surrounded regions shouldn't be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically. Solution: Find all the O s that are connected to the O s on the border, change them to #. Then scan the board, change O to X and # back to O. The process of finding the connected O s is just like tree traversal. O s on the border are the same level. Their children are the second level. And so on. So both BFS and DFS are good. I prefer BFS when pruning is not needed in favor of its readability./** * @param {character[][]} board * @return {void} Do not return anything, modify board in-place instead. */ let solve = function (board) { const height = board.length; if (height <= 1) { return; } const width = board[0].length; if (width <= 1) { return; } const rowend = height - 1; const colend = width - 1; const queue = []; for (let row = 0; row < height; row++) { if (board[row][0] === 'O') { board[row][0] = '#'; queue.push(row, 0); } if (board[row][colend] === 'O') { board[row][colend] = '#'; queue.push(row, colend); } } for (let col = 0; col < width; col++) { if (board[0][col] === 'O') { board[0][col] = '#'; queue.push(0, col); } if (board[rowend][col] === 'O') { board[rowend][col] = '#'; queue.push(rowend, col); } } while (queue.length > 0) { const row = queue.shift(); const col = queue.shift(); if (row < rowend && board[row + 1][col] === 'O') { board[row + 1][col] = '#'; queue.push(row + 1, col); } if (row > 0 && board[row - 1][col] === 'O') { board[row - 1][col] = '#'; queue.push(row - 1, col); } if (board[row][col + 1] === 'O') { board[row][col + 1] = '#'; queue.push(row, col + 1); } if (board[row][col - 1] === 'O') { board[row][col - 1] = '#'; queue.push(row, col - 1); } } for (let row = 0; row < height; row++) { for (let col = 0; col < width; col++) { if (board[row][col] === '#') { board[row][col] = 'O'; } else if (board[row][col] === 'O') { board[row][col] = 'X'; } } } }; Difficulty: Medium Related Topics: "Depth-first Search": https://leetcode.com/tag/depth-first-search "Breadth-first Search": https://leetcode.com/tag/breadth-first-search "Graph": https://leetcode.com/tag/graph Similar Questions: "Copy List with Random Pointer": https://leetcode.com/problems/copy-list-with-random-pointer➤ 133. Clone Graph Problem: Given the head of a graph, return a deep copy (clone) of the graph. Each node in the graph contains a label ( int) and a list ( List[UndirectedGraphNode]) of its neighbors. There is an edge between the given node and each of the nodes in its neighbors. OJ's undirected graph serialization (so you can understand error output): Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. As an example, consider the serialized graph {0,1,2#1,2#2,2}. The graph has a total of three nodes, and therefore contains three parts as separated by #. First node is labeled as 0. Connect node 0 to both nodes 1 and 2. Second node is labeled as 1. Connect node 1 to node 2. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. Visually, the graph looks like the following: 1 / \ / \ 0 --- 2 / \ \_/ Note: The information about the tree serialization is only meant so that you can understand error output if you get a wrong answer. You don't need to understand the serialization to solve the problem. Solution: DFS. Cache the visited node before entering the next recursion./** * Definition for undirected graph. * function UndirectedGraphNode(label) { * this.label = label; * this.neighbors = []; // Array of UndirectedGraphNode * } */ /** * @param {UndirectedGraphNode} graph * @return {UndirectedGraphNode} */ let cloneGraph = function (graph) { const cache = {}; return _clone(graph); function _clone(graph) { if (!graph) { return graph; } const label = graph.label; if (!cache[label]) { cache[label] = new UndirectedGraphNode(label); cache[label].neighbors = graph.neighbors.map(_clone); } return cache[label]; } }; /** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {TreeNode} root * @return {TreeNode} */ const upsideDownBinaryTree = function (root) { let curr = root; let next = null; let temp = null; let prev = null; while (curr !== null) { next = curr.left; curr.left = temp; temp = curr.right; curr.right = prev; prev = curr; curr = next; } return prev; }; // another const upsideDownBinaryTree = function (root) { if (root == null || root.left == null) { return root; } const newRoot = upsideDownBinaryTree(root.left); root.left.left = root.right; root.left.right = root; root.left = null; root.right = null; return newRoot; }; /** * @param {number[]} A * @return {number} */ const maxSubarraySumCircular = function (A) { let minSum = Infinity, sum = 0, maxSum = -Infinity, curMax = 0, curMin = 0; for (let a of A) { sum += a; curMax = Math.max(curMax + a, a); maxSum = Math.max(maxSum, curMax); curMin = Math.min(curMin + a, a); minSum = Math.min(minSum, curMin); } return maxSum > 0 ? Math.max(maxSum, sum - minSum) : maxSum; }; ➤ Balanced Binary Tree - LeetCode Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary tree is defined as: a binary tree in which the left and right subtrees of every node differ in height by no more than 1. Example 1: Input: root = [3,9,20,null,null,15,7] Output: true Example 2: Input: root = [1,2,2,3,3,null,null,4,4] Output: false Example 3: Input: root = [] Output: true Constraints: The number of nodes in the tree is in the range [0, 5000].-104 <= Node.val <= 104 Source# Convert Sorted Array to Binary Search Tree Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example: Given the sorted array: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \\ -3 9 / / -10 5 Source# Delete Node in a BST Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview. Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages: Search for a node to remove. If the node is found, delete the node. Follow up: Can you solve it with time complexity O(height of tree)? Example 1: Input: root = [5,3,6,2,4,null,7], key = 3 Output: [5,4,6,2,null,null,7] Explanation: Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the above BST. Please notice that another valid answer is [5,2,6,null,4,null,7] and it's also accepted. Example 2: Input: root = [5,3,6,2,4,null,7], key = 0 Output: [5,3,6,2,4,null,7] Explanation: The tree does not contain a node with value = 0. Example 3: Input: root = [], key = 0 Output: [] Constraints: The number of nodes in the tree is in the range [0, 104].-105 <= Node.val <= 105 Each node has a unique value. root is a valid binary search tree.-105 <= key <= 105 Source/** * @param {number[][]} intervals * @return {number} */ const minMeetingRooms = function (intervals) { const len = intervals.length; const starts = new Array(len); const ends = new Array(len); for (let i = 0; i < len; i++) { starts[i] = intervals[i][0]; ends[i] = intervals[i][1]; } starts.sort((a, b) => a - b); ends.sort((a, b) => a - b); let rooms = 0; let endsIdx = 0; for (let i = 0; i < len; i++) { if (starts[i] < ends[endsIdx]) rooms++; else endsIdx++; } return rooms; };
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    July 26, 2021 ExpressJS Apis lorem-ipsum SQL Tryit Editor v1.6 A database is a collection of data organized for easy retrieval and manipulation. We're concerned only with digital databases, those that run on computers or other electronic devices. Digital databases have been around since the 1960s. Relational databases, those which store "related" data, are the oldest and most common type of database in use today. Data Persistence A database is often necessary because our application or code requires data persistence. This term refers to data that is infrequently accessed and not likely to be modified. In less technical terms, the information will be safely stored and remain untouched unless intentionally modified. A familiar example of non-persistent data would be JavaScript objects and arrays, which reset each time the code runs. Relational Databases In relational databases, the data is stored in tabular format grouped into rows and columns (similar to spreadsheets). A collection of rows is called a table. Each row represents a single record in the table and is made up of one or more columns. These kinds of databases are relational because a relation is a mathematical idea equivalent to a table. So relational databases are databases that store their data in tables. Tables Below are some basic facts about tables: Tables organize data in rows and columns. Each row in a table represents one distinct record. Each column represents a field or attribute that is common to all the records. Fields should have a descriptive name and a data type appropriate for the attribute it represents. Tables usually have more rows than columns. Tables have primary keys that uniquely identify each row. Foreign keys represent the relationships with other tables. Overview SQL: SQL is a standard language, which means that it almost certainly will be supported, no matter how your database is managed. That said, be aware that the SQL language can vary depending on database management tools. This lesson focuses on a set of core commands that never change. Learning the standard commands is an excellent introduction since the knowledge transfers between database products. The syntax for SQL is English-like and requires fewer symbols than programming languages like C, Java, and JavaScript. It is declarative and concise, which means there is a lot less to learn to use it effectively. When learning SQL, it is helpful to understand that each command is designed for a different purpose. If we classify the commands by purpose, we'll end up with the following sub-categories of SQL: Data Definition Language (DDL): used to modify database objects. Some examples are: CREATE TABLE, ALTER TABLE, and DROP TABLE. Data Manipulation Language (DML): used to manipulate the data stored in the database. Some examples are: INSERT, UPDATE, and DELETE. Data Query Language (DQL): used to ask questions about the data stored in the database. The most commonly used SQL command is SELECT, and it falls in this category. Data Control Language (DCL): used to manage database security and user's access to data. These commands fall into the realm of Database Administrators. Some examples are GRANT and REVOKE. Transaction Control Commands: used for managing groups of statements that must execute as a unit or not execute at all. Examples are COMMIT and ROLLBACK. As a developer, you'll need to get familiar with DDL and become proficient using DML and DQL. This lesson will cover only DML and DQL commands. Overview The four SQL operations covered in this section will allow a user to query, insert, and modify a database table. Query A query is a SQL statement used to retrieve data from a database. The command used to write queries is SELECT, and it is one of the most commonly used SQL commands. The basic syntax for a SELECT statement is this: To see all the fields on a table, we can use a * as the selection. The preceding statement would show all the records and all the columns for each record in the employees table. To pick the fields we want to see, we use a comma-separated list: The return of that statement would hold all records from the listed fields. We can extend the SELECT command's capabilities using clauses for things like filtering, sorting, pagination, and more. It is possible to query multiple tables in a single query. But, in this section, we only perform queries on a single table. We will cover performing queries on multiple tables in another section. Insert To insert new data into a table, we'll use the INSERT command. The basic syntax for an INSERT statement is this: Using this formula, we can specify which values will be inserted into which fields like so: Modify Modifying a database consists of updating and removing records. For these operations, we'll use UPDATE and DELETE commands, respectively. The basic syntax for an UPDATE statement is: The basic syntax for a DELETE statement is: Follow Along Filtering results using WHERE clause When querying a database, the default result will be every entry in the given table. However, often, we are looking for a specific record or a set of records that meets certain criteria. A WHERE clause can help in both cases. Here's an example where we might only want to find customers living in Berlin. We can also chain together WHERE clauses using OR and AND to limit our results further. The following query includes only records that match both criteria. And this query includes records that match either criteria. These operators can be combined and grouped with parentheses to add complex selection logic. They behave similarly to what you're used to in programming languages. You can read more about SQLite operators from w3resource (Links to an external site.). To select a single record, we can use a WHERE statement with a uniquely identifying field, like an id: Other comparison operators also work in WHERE conditions, such as >, <, <=, and >=. Ordering results using the ORDER BY clause Query results are shown in the same order the data was inserted. To control how the data is sorted, we can use the ORDER BY clause. Let's see an example. We can pass a list of field names to order by and optionally choose asc or desc for the sort direction. The default is asc, so it doesn't need to be specified. Some SQL engines also support using field abbreviations when sorting. In this case, the results are sorted by the department in ascending order first and then by salary in descending order. The numbers refer to the fields' position in the selection portion of the query, so 1 would be name, 2 would be salary, and so on. Note that the WHERE clause should come after the FROM clause. The ORDER BY clause always goes last. Limiting results using the LIMIT clause When we wish to see only a limited number of records, we can use a LIMIT clause. The following returns the first ten records in the products table: LIMIT clauses are often used in conjunction with ORDER BY. The following shows us the five cheapest products: Inserting data using INSERT An insert statement adds a new record to the database. All non-null fields must be listed out in the same order as their values. Some fields, like ids and timestamps, may be auto-generated and do not need to be included in an INSERT statement. The values in an insert statement must not violate any restrictions and constraints that the database has in place, such as expected datatypes. We will learn more about constraints and schema design in a later section. Modifying recording using UPDATE When modifying a record, we identify a single record or a set of records to update using a WHERE clause. Then we can set the new value(s) in place. Technically the WHERE clause is not required, but leaving it off would result in every record within the table receiving the update. Removing records using DELETE When removing a record or set of records, we need only identify which record(s) to remove using a WHERE clause: Once again, the WHERE clause is not required, but leaving it off would remove every record in the table, so it's essential. Overview Raw SQL is a critical baseline skill. However, Node developers generally use an Object Relational Mapper (ORM) or query builder to write database commands in a backend codebase. Both ORMs and query builders are JavaScript libraries that allow us to interface with the database using a JavaScript version of the SQL language. For example, instead of a raw SQL SELECT: We could use a query builder to write the same logic in JavaScript: Query builders are lightweight and easy to get off the ground, whereas ORMs use an object-oriented model and provide more heavy lifting within their rigid structure. We will use a query builder called knex.js (Links to an external site.). Follow Along Knex Setup To use Knex in a repository, we'll need to add two libraries: knex is our query builder library, and sqlite3 allows us to interface with a sqlite database. We'll learn more about sqlite and other database management systems in the following module. For now, know that you need both libraries. Next, we use Knex to set up a config file: To use the query builder elsewhere in our code, we need to call knex and pass in a config object. We'll be discussing Knex configuration more in a future module. Still, we only need the client, connection, and useNullAsDefault keys as shown above. The filename should point towards the pre-existing database file, which can be recognized by the .db3 extension. GOTCHA: The file path to the database should be with respect to the root of the repo, not the configuration file itself. Once Knex is configured, we can import the above config file anywhere in our codebase to access the database. The db object provides methods that allow us to begin building queries. SELECT using Knex In Knex, the equivalent of SELECT * FROM users is: There's a simpler way to write the same command: Using this, we could write a GET endpoint. NOTE: All Knex queries return promises. Knex also allows for a where clause. In Knex, we could write SELECT * FROM users WHERE id=1 as This method will resolve to an array containing a single entry like so: [{ id: 1, name: 'bill' }]. Using this, we might add a GET endpoint where a specific user: INSERT using Knex In Knex, the equivalent of INSERT INTO users (name, age) VALUES ('Eva', 32) is: The insert method in Knex will resolve to an array containing the newly created id for that user like so: [3]. UPDATE using Knex In knex, the equivalent of UPDATE users SET name='Ava', age=33 WHERE id=3; is: Note that the where method comes before update, unlike in SQL. Update will resolve to a count of rows updated. DELETE using Knex In Knex, the equivalent of DELETE FROM users WHERE age=33; is: Once again, the where must come before the del. This method will resolve to a count of records removed. Day #2: Overview SQLlite Studio is an application that allows us to create, open, view, and modify SQLite databases. To fully understand what SQLite Studio is and how it works, we must also understand the concept of the Database Management Systems (DBMS). Follow Along What is a DBMS? To manage digital databases we use specialized software called D ata B ase M anagement S ystems (DBMS). These systems typically run on servers and are managed by D ata B ase A dministrators (DBAs). In less technical terms, we need a type of software that will allow us to create, access, and generally manage our databases. In the world of relational databases, we specifically use Relational Database Mangement Systems (RDBMs). Some examples are Postgres, SQLite, MySQL, and Oracle. Choosing a DBMS determines everything from how you set up your database, to where and how the data is stored, to what SQL commands you can use. Most systems share the core of the SQL language that you've already learned. In other words, you can expect SELECT, UPDATE, INSERT, WHERE , and the like to be the same across all DBMSs, but the subtleties of the language may vary. What is SQLite? SQLite is the DBMS, as the name suggests, it is a more lightweight system and thus easier to get set up than some others. SQLite allows us to store databases as single files. SQLite projects have a .db3 extension. That is the database. SQLite is not a database (like relational, graph, or document are databases) but rather a database management system. Opening an existing database in SQLite Studio One useful visual interface we might use with a SQLite database is called SQLite Studio. Install SQLITE Studio here. (Links to an external site.) Once installed, we can use SQLite Studio to open any .db3 file from a previous lesson. We may view the tables, view the data, and even make changes to the database. For a more detailed look at SQLite Studio, follow along in the video above. Overview A database schema is the shape of our database. It defines what tables we'll have, which columns should exist within the tables and any restrictions on each column. A well-designed database schema keeps the data well organized and can help ensure high-quality data. Note that while schema design is usually left to Database Administrators (DBAs), understanding schema helps when designing APIs and database logic. And in a smaller team, this step may fall on the developer. Follow Along For a look at schema design in SQLite Studio, follow along in the video above. When designing a single table, we need to ask three things: What fields (or columns) are present? What type of data do we expect for each field? Are there other restrictions needed for each column? Looking at the following schema diagram for an accounts table, we can the answer to each other those questions: Untitled Table Fields Choosing which fields to include in a table is relatively straight forward. What information needs to be tracked regarding this resource? In the real world, this is determined by the intended use of the product or app. However, this is one requirement every table should satisfy: a primary key. A primary key is a way to identify each entry in the database uniquely. It is most often represented as a auto-incrementing integer called id or [tablename]Id. Datatypes Each field must also have a specified datatype. The datatype available depends on our DBMS. Some supported datatype in SQLite include: Null: Missing or unknown information. Integer: Whole numbers. Real: Any number, including decimals. Text: Character data. Blob: a large binary object that can be used to store miscellaneous data. Any data inserted into the table must match the datatypes determined in schema design. Constraints Beyond datatypes, we may add additional constraints on each field. Some examples include: Not Null: The field cannot be left empty Unique: No two records can have the same value in this field Primary key: - Indicates this field is the primary key. Both the not null and unique constraints will be enforced. Default: - Sets a default value if none is provided. As with data types, any data that does not satisfy the schema constraints will be rejected from the database. Multi-Table Design Another critical component of schema design is to understand how different tables relate to each other. This will be covered in later lesson. Overview Knex provides a schema builder, which allows us to write code to design our database schema. However, beyond thinking about columns and constraints, we must also consider updates. When a schema needs to be updated, a developer must feel confident that the changes go into effect everywhere. This means schema updates on the developer's local machine, on any testing or staging versions, on the production database, and then on any other developer's local machines. This is where migrations come into play. A database migration describes changes made to the structure of a database. Migrations include things like adding new objects, adding new tables, and modifying existing objects or tables. Follow Along Knex Cli To use migrations (and to make Knex setup easier), we need to use knex cli. Install knex globally with npm install -g knex. This allows you to use Knex commands within any repo that has knex as a local dependency. If you have any issues with this global install, you can use the npx knex command instead. Initializing Knex To start, add the knex and sqlite3 libraries to your repository. npm install knex sqlite3 We've seen how to use manually create a config object to get started with Knex, but the best practice is to use the following command: Or, if Knex isn't globally installed: This command will generate a file in your root folder called knexfile.js. It will be auto populated with three config objects, based on different environments. We can delete all except for the development object. We'll need to update the location (or desired location) of the database as well as add the useNullAsDefault option. The latter option prevents crashes when working with sqlite3. Now, wherever we configure our database, we may use the following syntax instead of hardcoding in a config object. Knex Migrations Once our knexfile is set up, we can begin creating migrations. Though it's not required, we are going to add an addition option to the config object to specify a directory for the migration files. We can generate a new migration with the following command: knex migrate:make [migration-name] If we needed to create an accounts table, we might run: knex migrate:make create-accounts Note that inside data/migrations/ a new file has appeared. Migrations have a timestamp in their filenames automatically. Wither you like this or not, do not edit migration names. The migration file should have both an up and a down function. Within the up function, we write the ended database changes. Within the down function, we write the code to undo the up functions. This allows us to undo any changes made to the schema if necessary. References for these methods are found in the schema builder section of the Knex docs (Links to an external site.). At this point, the table is not yet created. To run this (and any other) migrations, use the command: knex migrate:latest Note if the database does not exist, this command will auto-generate one. We can use SQLite Studio to confirm that the accounts table has been created. Changes and Rollbacks If later down the road, we realize you need to update your schema, you shouldn't edit the migration file. Instead, you will want to create a new migration with the command: knex migrate:make accounts-schema-update Once we've written our updates into this file we save and close with: knex migrate:latest If we migrate our database and then quickly realize something isn't right, we can edit the migration file. However, first, we need to rolllback (or undo) our last migration with: knex migrate:rollback Finally, we are free to rerun that file with knex migrate latest. NOTE: A rollback should not be used to edit an old migration file once that file has accepted into a main branch. However, an entire team may use a rollback to return to a previous version of a database. Overview Knex provides a schema builder, which allows us to write code to design our database schema. However, beyond thinking about columns and constraints, we must also consider updates. When a schema needs to be updated, a developer must feel confident that the changes go into effect everywhere. This means schema updates on the developer's local machine, on any testing or staging versions, on the production database, and then on any other developer's local machines. This is where migrations come into play. A database migration describes changes made to the structure of a database. Migrations include things like adding new objects, adding new tables, and modifying existing objects or tables. Follow Along Knex Cli To use migrations (and to make Knex setup easier), we need to use knex cli. Install knex globally with npm install -g knex. This allows you to use Knex commands within any repo that has knex as a local dependency. If you have any issues with this global install, you can use the npx knex command instead. Initializing Knex To start, add the knex and sqlite3 libraries to your repository. npm install knex sqlite3 We've seen how to use manually create a config object to get started with Knex, but the best practice is to use the following command: Or, if Knex isn't globally installed: This command will generate a file in your root folder called knexfile.js. It will be auto populated with three config objects, based on different environments. We can delete all except for the development object. We'll need to update the location (or desired location) of the database as well as add the useNullAsDefault option. The latter option prevents crashes when working with sqlite3. Now, wherever we configure our database, we may use the following syntax instead of hardcoding in a config object. Knex Migrations Once our knexfile is set up, we can begin creating migrations. Though it's not required, we are going to add an addition option to the config object to specify a directory for the migration files. We can generate a new migration with the following command: knex migrate:make [migration-name] If we needed to create an accounts table, we might run: knex migrate:make create-accounts Note that inside data/migrations/ a new file has appeared. Migrations have a timestamp in their filenames automatically. Wither you like this or not, do not edit migration names. The migration file should have both an up and a down function. Within the up function, we write the ended database changes. Within the down function, we write the code to undo the up functions. This allows us to undo any changes made to the schema if necessary. References for these methods are found in the schema builder section of the Knex docs (Links to an external site.). At this point, the table is not yet created. To run this (and any other) migrations, use the command: knex migrate:latest Note if the database does not exist, this command will auto-generate one. We can use SQLite Studio to confirm that the accounts table has been created. Changes and Rollbacks If later down the road, we realize you need to update your schema, you shouldn't edit the migration file. Instead, you will want to create a new migration with the command: knex migrate:make accounts-schema-update Once we've written our updates into this file we save and close with: knex migrate:latest If we migrate our database and then quickly realize something isn't right, we can edit the migration file. However, first, we need to rolllback (or undo) our last migration with: knex migrate:rollback Finally, we are free to rerun that file with knex migrate latest. NOTE: A rollback should not be used to edit an old migration file once that file has accepted into a main branch. However, an entire team may use a rollback to return to a previous version of a database. Overview Often we want to pre-populate our database with sample data for testing. Seeds allow us to add and reset sample data easily. Follow Along The Knex command-line tool offers a way to seed our database; in other words, pre-populate our tables. Similarly to migrations, we want to customize where our seed files are generated using our knexfile To create a seed run: knex seed:make 001-seedName Numbering is a good idea because Knex doesn't attach a timestamp to the name like migrate does. Adding numbers to the file name, we can control the order in which they run. We want to create seeds for our accounts table: knex seed:make 001-accounts A file will appear in the designated seed folder. Run the seed files by typing: knex seed:run You can now use SQLite Studio to confirm that the accounts table has two entries. Day #3: Overview Foreign keys are a type of table field used for creating links between tables. Like primary keys, they are most often integers that identify (rather than store) data. However, whereas a primary key is used to id rows in a table, foreign keys are used to connect a record in one table to a record in a second table. Follow Along Consider the following farms and ranchers tables. Untitled Untitled The farm id in the ranchers table is an example of a foreign key. Each entry in the farm id (foreign key) column corresponds to an id (primary key) in the farms table. This allows us to track which farm each rancher belongs to while keeping the tables normalized. If we could only see the ranchers table, we would know that John, Jane, and Jen all work together and that Jim and Jay also work together. However, to know where any of them work, we would need to look at the farms table. Now that we understand the basics of querying data from a single table, let's move on to selecting data from multiple tables using JOIN operations. Overview We can use a JOIN to combine query data from multiple tables using a single SELECT statement. There are different types of joins; some are listed below: inner joins. outer joins. left joins. right joins. cross joins. non-equality joins. self joins. Using joins requires that the two tables of interest contain at least one field with shared information. For example, if a departments table has an id field, and an employee table has a department_id field, and the values that exist in the id column of the departments table live in the department_id field of the employee table, we can use those fields to join both tables like so: This query will return the data from both tables for every instance where the ON condition is true. If there are employees with no value for department id or where the value stored in the field does not correspond to an existing id in the departments table, then that record will NOT be returned. In a similar fashion, any records from the departments table that don't have an employee associated with them will also be omitted from the results. Basically, if the id* does not show as the value of department_id for an employee, it won't be able to join. We can shorten the condition by giving the table names an alias. This is a common practice. Below is the same example using aliases, picking which fields to return and sorting the results: Notice that we can take advantage of white space and indentation to make queries more readable. There are several ways of writing joins, but the one shown here should work on all database management systems and avoid some pitfalls, so we recommend it. The syntax for performing a similar join using Knex is as follows: Follow Along A good explanation of how the different types of joins can be seen in this article from w3resource.com (Links to an external site.). What is SQL Joins? An SQL JOIN clause combines rows from two or more tables. It creates a set of rows in a temporary table. How to Join two tables in SQL? A JOIN works on two or more tables if they have at least one common field and have a relationship between them. JOIN keeps the base tables (structure and data) unchanged. Join vs. Subquery JOINs are faster than a subquery and it is very rare that the opposite. In JOINs the RDBMS calculates an execution plan, that can predict, what data should be loaded and how much it will take to processed and as a result this process save some times, unlike the subquery there is no pre-process calculation and run all the queries and load all their data to do the processing. A JOIN is checked conditions first and then put it into table and displays; where as a subquery take separate temp table internally and checking condition. When joins are using, there should be connection between two or more than two tables and each table has a relation with other while subquery means query inside another query, has no need to relation, it works on columns and conditions. SQL JOINS: EQUI JOIN and NON EQUI JOIN The are two types of SQL JOINS - EQUI JOIN and NON EQUI JOIN SQL EQUI JOIN : The SQL EQUI JOIN is a simple SQL join uses the equal sign(=) as the comparison operator for the condition. It has two types - SQL Outer join and SQL Inner join. SQL NON EQUI JOIN : The SQL NON EQUI JOIN is a join uses comparison operator other than the equal sign like >, <, >=, <= with the condition. SQL EQUI JOIN : INNER JOIN and OUTER JOIN The SQL EQUI JOIN can be classified into two types - INNER JOIN and OUTER JOIN SQL INNER JOIN This type of EQUI JOIN returns all rows from tables where the key record of one table is equal to the key records of another table. SQL OUTER JOIN This type of EQUI JOIN returns all rows from one table and only those rows from the secondary table where the joined condition is satisfying i.e. the columns are equal in both tables. In order to perform a JOIN query, the required information we need are: a) The name of the tables b) Name of the columns of two or more tables, based on which a condition will perform. Syntax: Parameters: Untitled Pictorial Presentation of SQL Joins: Example: Sample table: company Sample table: foods To join two tables 'company' and 'foods', the following SQL statement can be used : SQL Code: Copy Output: Overview While we can write database code directly into our endpoints, best practices dictate that all database logic exists in separate, modular methods. These files containing database access helpers are often called models Follow Along To handle CRUD operations for a single resource, we would want to create a model (or database access file) containing the following methods: Each of these functions would use Knex logic to perform the necessary database operation. For each method, we can choose what value to return. For example, we may prefer findById() to return a single user object rather than an array. We can also use existing methods like findById() to help add() return the new user (instead of just the id). Once all methods are written as desired, we can export them like so:…and use the helpers in our endpoints There should no be knex code in the endpoints themselves. Day #4: Overview Normalization is the process of designing or refactoring database tables for maximum consistency and minimum redundancy. With objects, we're used to denormalized data, stored with ease of use and speed in mind. Non-normalized tables are considered ineffective in relational databases. Follow Along Data normalization is a deep topic in database design. To begin thinking about it, we'll explore a few basic guidelines and some data examples that violate these rules. Normalization Guidelines Each record has a primary key. No fields are repeated. All fields relate directly to the key data. Each field entry contains a single data point. There are no redundant entries. Denormalized Data Untitled This table has two issues. There is no proper id field (as multiple farms may have the same name), and multiple fields are representing the same type of data: animals. Untitled While we have now eliminated the first two issues, we now have multiple entries in one field, separated by commas. This isn't good either, as its another example of denormalization. There is no "array" data type in a relational database, so each field must contain only one data point. Untitled Now we've solved the multiple fields issue, but we created repeating data (the farm field), which is also an example of denormalization. As well, we can see that if we were tracking additional ranch information (such as annual revenue), that field is only vaguely related to the animal information. When these issues begin arising in your schema design, it means that you should separate information into two or more tables. Anomalies Obeying the above guidelines prevent anomalies in your database when inserting, updating, or deleting. For example, imagine if the revenue of Beech Ranch changed. With our denormalized schema, it may get updated in some records but not others: Untitled Similarly, if Beech Ranch shut down, there would be three (if not more) records that needed to be deleted to remove a single farm. Thus a denormalized table opens the door for contradictory, confusing, and unusable data. Challenge What issues does the following table have? Untitled Overview There are three types of relationships: One to one. One to many. Many to many. Determining how data is related can provide a set of guidelines for table representation and guides the use of foreign keys to connect said tables. Follow Along One to One Relationships Imagine we are storing the financial projections for a series of farms. We may wish to attach fields like farm name, address, description, projected revenue, and projected expenses. We could divide these fields into two categories: information related to the farm directly (name, address, description) and information related to the financial projections (revenue, expenses). We would say that farms and projections have a one-to-one relationship. This is to say that every farm has exactly one projection, and every project corresponds to exactly one farm. This data can be represented in two tables: farms and projections Untitled Untitled The farm_id is the foreign key that links farms and projections together. Notes about one-to-one relationships: The foreign key should always have a unique constraint to prevent duplicate entries. In the example above, we wouldn't want to allow multiple projections records for one farm. The foreign key can be in either table. For example, we may have had a projection_id in the farms table instead. A good rule of thumb is to put the foreign key in whichever table is more auxiliary to the other. You can represent one-to-one data in a single table without creating anomalies. However, it is sometimes prudent to use two tables as shown above to keep separate concerns in separate tables. One to Many Relationships Now imagine, we are storing the full-time ranchers employed at each farm. In this case, each rancher would only work at one farm however, each farm may have multiple ranchers. This is called a one-to-many relationship. This is the most common type of relationship between entities. Some other examples: One customer can have many orders. One user can have many posts. One post can have many comments. Manage this type of relationship by adding a foreign key on the "many" table of the relationship that points to the primary key on the "one" table. Consider the farms and ranchers tables. Untitled Untitled In a many-to-many relationship, the foreign key (in this case farm_id) should not be unique. Many to Many Relationships If we want to track animals on a farm as well, we must explore the many-to-many relationship. A farm has multiple animals, and multiple of each type of animal is present at multiple different farms. Some other examples: an order can have many products and the same product will appear in many orders. a book can have more than one author, and an author can write more than one book. To model this relationship, we need to introduce an intermediary table that holds foreign keys that reference the primary key on the related tables. We now have a farms, animals, and farm_animals table. Untitled Untitled Untitled While each foreign key on the intermediary table is not unique, the combinations of keys should be unique. Overview The Knex query builder library also allows us to create multi-table schemas include foreign keys. However, there are a few extra things to keep in mind when designing a multi-table schema, such as using the correct order when creating tables, dropping tables, seeding data, and removing data. We have to consider the way that delete and updates through our API will impact related data. Follow Along Foreign Key Setup In Knex, foreign key restrictions don't automatically work. Whenever using foreign keys in your schema, add the following code to your knexfile. This will prevent users from entering bad data into a foreign key column. Migrations Let's look at how we might track our farms and ranchers using Knex. In our migration file's up function, we would want to create two tables: Note that the foreign key can only be created after the reference table. In the down function, the opposite is true. We always want to drop a table with a foreign key before dropping the table it references. In the case of a many-to-many relationship, the syntax for creating an intermediary table is identical, except for one additional piece. We need a way to make sure our combination of foreign keys is unique. Seeds Order is also a concern when seeding. We want to create seeds in the same order we created our tables. In other words, don't create a seed with a foreign key, until that reference record exists. In our example, make sure to write the 01-farms seed file and then the 02-ranchers seed file. However, we run into a problem with truncating our seeds, because we want to truncate 02-ranchers before 01-farms. A library called knex-cleaner provides an easy solution for us. Run knex seed:make 00-cleanup and npm install knex-cleaner. Inside the cleanup seed, use the following code. This removes all tables (excluding the two tables that track migrations) in the correct order before any seed files run. Cascading If a user attempt to delete a record that is referenced by another record (such as attempting to delete Morton Ranch when entries in our ranchers table reference that record), by default, the database will block the action. The same thing can happen when updating a record when a foreign key reference. If we want that to override this default, we can delete or update with cascade. With cascade, deleting a record also deletes all referencing records, we can set that up in our schema.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    July 26, 2021 Blog Archive Blog Archive Blog Archive
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    September 11, 2021 Big O Computational Complexity Explained using gif animations Sorting Algorithms Bubble Sort Time Complexity: Quadratic O(n^2) The inner for-loop contributes to O(n), however in a worst case scenario the while loop will need to run n times before bringing all n elements to their final resting spot. Space Complexity: O(1) Bubble Sort will always use the same amount of memory regardless of n. https://gist.github.com/eengineergz/e67e56bed7c5a20a54851867ba5efef6 The first major sorting algorithm one learns in introductory programming courses. Gives an intro on how to convert unsorted data into sorted data. It's almost never used in production code because: It's not efficient It's not commonly used There is stigma attached to it Bubbling Up : Term that infers that an item is in motion, moving in some direction, and has some final resting destination. Bubble sort, sorts an array of integers by bubbling the largest integer to the top. https://gist.github.com/eengineergz/fd4acc0c89033bd219ebf9d3ec40b053 https://gist.github.com/eengineergz/80934783c628c70ac2a5a48119a82d54 Worst Case & Best Case are always the same because it makes nested loops. Double for loops are polynomial time complexity or more specifically in this case Quadratic (Big O) of: O(n²) Selection Sort Time Complexity: Quadratic O(n^2) Our outer loop will contribute O(n) while the inner loop will contribute O(n / 2) on average. Because our loops are nested we will get O(n²); Space Complexity: O(1) Selection Sort will always use the same amount of memory regardless of n. https://gist.github.com/eengineergz/4abc0fe0bf01599b0c4104b0ba633402 Selection sort organizes the smallest elements to the start of the array. Summary of how Selection Sort should work: Set MIN to location 0 Search the minimum element in the list. Swap with value at location Min Increment Min to point to next element. Repeat until list is sorted. https://gist.github.com/eengineergz/61f130c8e0097572ed908fe2629bdee0 Insertion Sort Time Complexity: Quadratic O(n^2) Our outer loop will contribute O(n) while the inner loop will contribute O(n / 2) on average. Because our loops are nested we will get O(n²); Space Complexity: O(n) Because we are creating a subArray for each element in the original input, our Space Comlexity becomes linear. https://gist.github.com/eengineergz/a9f4b8596c7546ac92746db659186d8c Merge Sort Time Complexity: Log Linear O(nlog(n)) Since our array gets split in half every single time we contribute O(log(n)). The while loop contained in our helper merge function contributes O(n) therefore our time complexity is O(nlog(n)); Space Complexity: O(n) We are linear O(n) time because we are creating subArrays. Example of Merge Sort https://gist.github.com/eengineergz/18fbb7edc9f5c4820ccfcecacf3c5e48 https://gist.github.com/eengineergz/cbb533137a7f957d3bc4077395c1ff64 Merge sort is O(nlog(n)) time. We need a function for merging and a function for sorting. Steps: If there is only one element in the list, it is already sorted; return the array. Otherwise, divide the list recursively into two halves until it can no longer be divided. Merge the smallest lists into new list in a sorted order. Quick Sort Time Complexity: Quadratic O(n^2) Even though the average time complexity O(nLog(n)), the worst case scenario is always quadratic. Space Complexity: O(n) Our space complexity is linear O(n) because of the partition arrays we create. QS is another Divide and Conquer strategy. Some key ideas to keep in mind: It is easy to sort elements of an array relative to a particular target value. An array of 0 or 1 elements is already trivially sorted. https://gist.github.com/eengineergz/24bcbc5248a8c4e1671945e9512da57e Binary Search Time Complexity: Log Time O(log(n)) Space Complexity: O(1) Recursive Solution https://gist.github.com/eengineergz/c82c00a4bcba4b69b7d326d6cad3ac8c Min Max Solution https://gist.github.com/eengineergz/eb8d1e1684db15cc2c8af28e13f38751 https://gist.github.com/eengineergz/bc3f576b9795ccef12a108e36f9f820a Must be conducted on a sorted array. Binary search is logarithmic time, not exponential b/c n is cut down by two, not growing. Binary Search is part of Divide and Conquer. Insertion Sort Works by building a larger and larger sorted region at the left-most end of the array. Steps: If it is the first element, and it is already sorted; return 1. Pick next element. Compare with all elements in the sorted sub list Shift all the elements in the sorted sub list that is greater than the value to be sorted. Insert the value Repeat until list is sorted. https://gist.github.com/eengineergz/ffead1de0836c4bcc6445780a604f617
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    September 30, 2021 Awesome GraphQL The Death Of REST Table of Contents Specification Community GraphQL Meetups Libraries Javascript Typescript Ruby PHP Python Java C/C++ Go Scala Perl.NET Erlang Elixir Haskell SQL Lua Elm Clojure ClojureScript Swift OCaml Rust R Julia Kotlin Unity Crystal Tools Services Databases Examples Javascript Typescript Ruby Go Scala Python Elixir PHP ReasonML Videos Blogs Posts Workshoppers Specification facebook/graphql - Working Draft of the Specification for GraphQL created by Facebook. Community Slack - Share and help people on the chat. Get your invite here#graphql on Freenode - The official IRC channel for GraphQL Facebook - Group for discussions, articles and knowledge sharing Twitter - Use the hashtag #graphql StackOverflow - Questions and answers. Use the tag graphql GraphQL APIs - A collective list of public GraphQL APIs GraphQL World - The fastest growing community of GraphQL developers GraphQL Meetups Berlin Buenos Aires Dallas-Fort Worth Istanbul London Melbourne Munich New York City San Francisco Sydney Tel Aviv Toronto Libraries JavaScript Libraries GraphQL.js - A reference implementation of GraphQL for JavaScript. express-graphql - GraphQL Express Middleware. koa-graphql - GraphQL Koa Middleware. hapi-graphql - Create a GraphQL HTTP server with Hapi. codemirror-graphql - GraphQL mode and helpers for CodeMirror. graphql-schema - Create GraphQL schemas with a fluent/chainable interface. graphql-sequelize - Sequelize helpers for GraphQL. graphql-sequelize-crud - Automatically generate queries and mutations from Sequelize models. graffiti - Node.js GraphQL ORM. graffiti-mongoose - Mongoose (MongoDB) adapter for graffiti (Node.js GraphQL ORM). babel-plugin-graphql - Babel plugin that compile GraphQL tagged template strings. adrenaline - React bindings for Redux with Relay in mind. graphql-bookshelf - Some help defining GraphQL schema around BookshelfJS models. graphql-bookshelfjs - A simple bridge between your graphql queries and your bookshelf models, perform batched and optimised queries. graph.ql - Faster and simpler technique for creating and querying GraphQL schemas. react-reach - A library to communicate with Graphql through Redux Lokka - Simple JavaScript client for GraphQL, which you can use anywhere. Strapi - Open-source Node.js framework that supports "GraphQL" out of the box. GraysQL - A GraphQL manager and loader. graysql-orm-loader - A GraysQL extension to load a GraphQL schema from an ORM. Annotated GraphQL - Proof of Concept for annotations in GraphQL (i.e.: transform an existing REST api into a GraphQL endpoint). Apollo Client - A well-documented GraphQL client. Has React and Angular bindings. graphql-tools - Tool library for building and maintaining GraphQL-JS servers. graphql-anywhere - Run a GraphQL query anywhere, against any data, with no schema. graphql-tag - A JavaScript template literal tag that parses GraphQL queries. modelizr - A library for simplifying the process of writing GraphQL queries, mocking them and normalizing their responses. vue-apollo - Vue integration for apollo. graphql-thinky - Build an optimized GraphQL schema from Thinky RethinkDB models. graphql-pouch - A GraphQL-API runtime on top of PouchDB created by GraphQL shorthand notation as a self contained service with CouchDB synchronization. gql-tools - Tool library with CLI for schema generation and manipulation. graphql-iso-date - A GraphQL date scalar type to be used with GraphQL.js. This scalar represents a date in the ISO 8601 format YYYY-MM-DD. graphql-compose - Tool which allows you to construct flexible graphql schema from different data sources via plugins. node-graphjoiner - Create GraphQL APIs using joins, SQL or otherwise. FetchQL - GraphQL query client with Fetch Join Monster - A GraphQL-to-SQL query execution layer for batch data fetching. Create-GraphQL - Command-line utility to build production-ready servers with GraphQL. GraphQL-Pokémon - Get information of a Pokémon with GraphQL! graphql-factory - Create GraphQL types from JSON definitions ChromeiQL - Chrome extension to use GraphiQL anywhere graphql-auto-mutation - Automatically generates functions for mutations specified in a GraphQL schema. GraphiteJS - Full stack GraphQL framework. loopback-graphql - GraphQL Server for Loopback. parasprite - Describe your GraphQL schema using chainable interface. GraphQL.js - JavaScript GraphQL Client for Browser and Node.js Usage graphql-sync - Promise-free wrapper to GraphQL.js for synchronous environments apollo-fetch - Lightweight GraphQL client that supports custom fetch functions, middleware, and afterware Spikenail - Node.js framework for building GraphQL API almost without coding. graphql-weaver - A tool to combine, link and transform GraphQL schemas; combine multiple GraphQL servers into one API. graphql-lodash - Data manipulation for GraphQL queries with lodash syntax. apollo-angular - Angular integration for Apollo. graphql-resolvers - Resolver composition library for GraphQL. apollo-resolvers - Expressive and composable resolvers for Apollo Server and graphql-tools. apollo-errors - Machine-readable custom errors for Apollo Server. graphql-disable-introspection - Graphql Disable Introspection mongo-graphql-starter - Flexible and robust Mongo based resolvers for Node. altair-express-middleware - An express middleware for mounting an instance of Altair GraphQL client. graphql-cost-analysis - A Graphql query cost analyzer. Relay Related relay - Relay is a JavaScript framework for building data-driven React applications. graphql-relay-js - A library to help construct a graphql-js server supporting react-relay. sequelize-relay - Serverside library that connects sequelize and graphql-relay-js together. babel-plugin-react-relay - Babel Plugin for Relay with support for JSON & graphql-js schemas and URL endpoints. babel-relay-plugin - Babel Relay Plugin for transpiling GraphQL queries for use with Relay. react-router-relay - Relay integration for React Router. relay-local-schema - Use Relay without a GraphQL server. relay-sink - Use Relay to fetch and store data outside of a React component. recompose-relay - Recompose helpers for Relay. Graylay - A GraysQL extension to create a Relay compatible Schema. Apollo Client - A simple alternative to Relay, comes with React and Angular bindings. react-relay-network-layer - A network layer for Relay with query batching and middleware support (urlThunk, retryThunk, auth, defer and other). relay-subscriptions - Subscription support for Relay. Portfolio Relay Example - An example website that fetches data from various apis and uses Relay and GraphQL to feed the data to React components! Relay Pokédex - Project using GraphQL Pokémon to show how powerful Relay is. vue-relay - A framework for building GraphQL-driven Vue.js applications. TypeScript Libraries TypeGraphQL - Create GraphQL schema and resolvers with TypeScript, using classes and decorators! Vesper - NodeJS framework that helps you to create scalable, maintainable, extensible, declarative and fast GraphQL-based server applications. graphql-strong - Define your GraphQL schemas with confidence that your values are correct. graphql-to-typescript - Compiles GraphQL files into an importable typescript module with type definitions graphql-decorator - Helps to build GraphQL schema with TypeScript. graphql-schema-decorator - This package makes possible the use of decorators to define a GraphQL schema. graphql-typescript - Define and build GraphQL Schemas using typed classes typegql - Create GraphQL schema with type-safe class decorators. Ruby Libraries graphql-ruby - Ruby implementation of Facebook's GraphQL. graphql-parser - A small ruby gem wrapping the libgraphqlparser C library for parsing GraphQL. graphql-client - A Ruby library for declaring, composing and executing GraphQL queries. graphql-batch - A query batching executor for the graphql gem. batch-loader – A powerful tool to avoid N+1 queries without extra dependencies or primitives. graphql-guard - A simple field-level authorization for the graphql gem. PHP Libraries graphql-php - A PHP port of GraphQL reference implementation. graphql-relay-php - Relay helpers for GraphQL & PHP. API Platform - API framework compatible with Symfony having native GraphQL support. laravel-graphql - Facebook GraphQL for Laravel 5. laravel-graphql-relay - A Laravel library to help construct a server supporting react-relay. graphql-mapper - This library allows to build a GraphQL schema based on your model. graphql-bundle - GraphQL Bundle for Symfony 2. overblog/graphql-bundle - This bundle provides tools to build a complete GraphQL server in your Symfony App. Supports react-relay. GraphQL – Well documented PHP implementation with no dependencies. GraphQL Symfony Bundle – GraphQL Bundle for the Symfony 3 (supports 2.6+). WPGraphQL - WordPress plugin that exposes a Relay compliant GraphQL endpoint graphql-wp – a WordPress plugin that exposes a GraphQL endpoint. eZ Platform GraphQL Bundle - GraphQL Bundle for the eZ Platform Symfony CMS. GraphQL Middleware - GraphQL Psr7 Middleware Zend Expressive GraphiQL Extension - GraphiQL extension for zend expressive GraphQL for PHP7 - A batteries-included, standard-compliant and easy to work with implementation of the GraphQL specification in PHP7 (based on the reference implementation). Python Libraries graphql-parser - GraphQL parser for Python. graphql-core - GraphQL implementation for Python. graphql-relay-py - A library to help construct a graphql-py server supporting react-relay. graphql-parser-python - A python wrapper around libgraphqlparser. graphene - A package for creating GraphQL schemas/types in a Pythonic easy way. graphene-gae - Adds GraphQL support to Google AppEngine (GAE). flask-graphql - Adds GraphQL support to your Flask application. python-graphql-client - Simple GraphQL client for Python 2.7+ python-graphjoiner - Create GraphQL APIs using joins, SQL or otherwise. graphene-django - A Django integration for Graphene. Java Libraries graphql-java - GraphQL Java implementation. graphql-java-type-generator - Auto-generates types for use with GraphQL Java schemagen-graphql - Schema generation and execution package that turns POJO's into a GraphQL Java queryable set of objects. Enables exposing any service as a GraphQL service using Annotations. graphql-java-annotations - Provides annotations-based syntax for schema definition with GraphQL Java. spring-graphql-common - Spring Framework GraphQL Library. graphql-spring-boot - GraphQL and GraphiQL Spring Framework Boot Starters. neo4j-graphql - GraphQL bindings for Neo4j, generates and runs Cypher. vertx-graphql-service-discovery - Asynchronous GraphQL service discovery and querying for your microservices. vertx-dataloader - Port of Facebook DataLoader for efficient, asynchronous batching and caching in clustered GraphQL environments LiveGQL - GraphQL subscription client in Java. rdbms-to-graphql - A Java CLI program that generates a GraphQL schema from a JDBC data source. Rejoiner - Generates a GraphQL schema based on one or more gRPC microservices, or any other Protobuf source. graphql-spqr - GraphQL SPQR aims to make it dead simple to add a GraphQL API to any Java project. It works by dynamically generating a GraphQL schema from Java code. C/C++ Libraries libgraphqlparser - A GraphQL query parser in C++ with C and C++ APIs. Go Libraries graphql - An implementation of GraphQL for Go follows graphql-js machinebox/graphql - Simple low-level GraphQL client for Go graphql-relay-go - A Go/Golang library to help construct a server supporting react-relay. graphql-go - GraphQL server with a focus on ease of use. c-graphqlparser - Go-gettable version of the libgraphqlparser C library for parsing GraphQL. tallstreet-graphql - GraphQL parser and server for Go that leverages libgraphqlparser go-graphql - A powerful GraphQL server implementation for Golang dataloader - Implementation of Facebook's DataLoader in Golang Scala Libraries sangria - Scala GraphQL client and server library. sangria-relay - Sangria Relay Support. graphql-scala - An attempt to get GraphQL going with Scala. Perl Libraries Perl6-GraphQL - GraphQL for Perl6. graphql-perl - GraphQL for Perl5..NET Libraries graphql-dotnet - GraphQL for .NET. Conventions - Reflection-based schema generation for .NET. graphql-net - GraphQL to IQueryable for .NET FSharp.Data.GraphQL - FSharp GraphQL. GraphQL.Client - GraphQL Client for .NET. Erlang Libraries graphql-erlang - Pure Erlang implementation with IDL and pattern-matching. Elixir Libraries absinthe-graphql - Fully Featured Elixir GraphQL Library. graphql-elixir - GraphQL Elixir. plug_graphql - Plug integration for GraphQL Elixir. graphql_relay - Relay helpers for GraphQL Elixir. graphql_parser - Elixir bindings for libgraphqlparser graphql - Elixir GraphQL parser. plot - GraphQL parser and resolver for Elixir. Haskell Libraries graphql-haskell - GraphQL AST and parser for Haskell. SQL Libraries GraphpostgresQL - GraphQL for Postgres. sql-to-graphql - Generate a GraphQL API based on your SQL database structure. PostGraphile - A GraphQL API created by reflection over a PostgreSQL schema. rdbms-to-graphql - A Java CLI program that generates a GraphQL schema from a JDBC data source. Prisma - Turn your database into a GraphQL API. Prisma lets you design your data model and have a production ready GraphQL API online in minutes. tuql - Automatically create a GraphQL server from any sqlite database. Lua Libraries graphql-lua - GraphQL for Lua. Elm Libraries jamesmacaulay/elm-graphql - Client library that lets you build GraphQL queries in Elm. ghivert/elm-graphql - Client library that lets you build GraphQL queries in Elm with your own decoders. jahewson/elm-graphql - Command-line tool that generates Elm code from queries in .graphql files. Clojure Libraries graphql-clj - A Clojure library designed to provide GraphQL implementation. lacinia - GraphQL implementation in pure Clojure. alumbra - Simple & Elegant GraphQL for Clojure! ClojureScript Libraries speako - A ClojureScript/NPM compiler for GraphQL Schema Language. venia - A Clojure(Script) GraphQL query generation Swift Libraries GraphQL - Build GraphQL APIs with Swift. Graphiti - Build Swiftier GraphQL APIs with Swift. Gryphin - Type-safe GraphQL client for iOS and MacOS written in Swift. Apollo-iOS - Strongly typed, code-generating, caching GraphQL client for Swift. LiveGQL - GraphQL Subscription client in Swift. OCaml Libraries ocaml-graphql-server - GraphQL servers in OCaml. Rust Libraries juniper - GraphQL server library for Rust. R Libraries graphql - Bindings to libgraphqlparser for R. gqlr - GraphQL server package for R. ghql - GraphQL client package for R. Julia Libraries Diana.jl - Julia client for GraphQL. Kotlin Libraries ktq - Kotlin gradle plugin SDL type generator & runtime client Unity Libraries graphQL-client-unity - A Unity client for GraphQL. Crystal Libraries graphql-crystal - A graphql implementation for Crystal Tools graphiql - An in-browser IDE for exploring GraphQL. GraphQL Playground - GraphQL IDE that supports multi-column schema docs, tabs, query history, configuration of HTTP headers and GraphQL Subscriptions. GraphiQL.app - A light, Electron-based wrapper around GraphiQL. GraphQLviz - GraphQLviz marries GraphQL (schemas) with Graphviz. graphqlviz - GraphQL API visualizer in Node.js Relay Playground GraphQL AST Explorer - Explore the AST of a GraphQL document interactively GraphQLHub - Query public API's schemas (e.g. Reddit, Twitter, Github, etc) using GraphiQL js-graphql-intellij-plugin - GraphQL language support for IntelliJ IDEA and WebStorm, including Relay.QL tagged templates in JavaScript and TypeScript. gdom - DOM Traversing and Scraping using GraphQL. Annotated GraphQL Server - Server for annotated GraphQL showing how to transform a REST api into a GraphQL endpoint with annotations. Model Visualizer - A small webapp that generates an ERD-like visualization of a GraphQL endpoint from an introspection query. GraphQL Network - A chrome dev-tools extension for debugging GraphQL network requests. eslint-plugin-graphql - An ESLint plugin that checks your GraphQL strings against a schema. AST Explorer - Select "GraphQL" at the top, explore the GraphQL AST and highlight different parts by clicking in the query. vim-graphql - A Vim plugin that provides GraphQL file detection and syntax highlighting. GraphQL CMS - Use your existing GraphQL schema to generate simple for use, fully functional CMS in a couple steps. graphdoc - Static page generator for documenting GraphQL Schema. graphql-autocomplete - Autocomplete and lint from a GraphQL endpoint in Atom. GraphQL IDE - An extensive IDE for exploring GraphQL API's. Swagger to GraphQL - GraphQL types builder based on REST API described in Swagger. Allows to migrate to GraphQL from REST for 5 minutes GraphQL Voyager - Represent any GraphQL API as an interactive graph. GraphQL Docs - Instantly create beautiful GraphQL API docs hosted online. GraphQL Faker - 🎲 Mock or extend your GraphQL API with faked data. No coding required. ts-graphql-plugin - A language service plugin complete and validate GraphQL query in TypeScript template strings. Apollo Launchpad - Like JSFiddle for GraphQL server code, write and deploy a GraphQL API directly from your browser. Apollo Tracing - GraphQL extension that enables you to easily get resolver-level performance information as part of a GraphQL response. Altair GraphQL Client - A beautiful feature-rich GraphQL Client for all platforms. Apollo Storybook Decorator - Wrap your React Storybook stories with Apollo Client, provide mocks for isolated UI testing with GraphQL GraphQL Metrics - instrument GraphQL resolvers, logging response times and statuses (if there was an error or not) to the console as well as to InfluxDB. GraphQL Rover - GraphQL schema interactive navigation, rearrange nodes, search and explore types and fields. json-graphql-server - Get a full fake GraphQL API with zero coding in less than 30 seconds, based on a JSON data file. Insomnia – An full-featured API client with first-party GraphQL query editor RAN Toolkit - Production-ready toolkit/boilerplate with support for GraphQL, SSR, Hot-reload, CSS-in-JS, caching, and more. Databases ArangoDB - Multi-model database that supports GraphQL schemas in JavaScript inside the database. Dgraph - Scalable, distributed, low latency, high throughput Graph database with a GraphQL like language (called GraphQL+) as the query language. Dgrapqh can be queried with graphql by using dgraphql Services GraphCMS - GraphQL based Headless Content Management System. Graphcool - Your own GraphQL backend in under 5 minutes. Works with every GraphQL client such as Relay and Apollo. Hasura - Create tables and get a GraphQL backend in under 60s. Works on top of Postgres that you can directly access. No initial knowledge of graphql required. Reindex - Instant GraphQL Backend for Your React Apps. Scaphold - GraphQL as a service that includes API integrations such as Stripe and Mailgun. Tipe - Next Generation API-first CMS with a GraphQL or REST API. Stop letting your CMS decide how you build your apps. AWS AppSync - Serverless GraphQL Examples JavaScript Examples relay-starter-kit - Barebones starting point for a Relay application. react-starter-kit - Isomorphic web app boilerplate (Node.js/Express, GraphQL, React) nodejs-api-starter - Boilerplate and tooling for authoring data API backends with Node.js and GraphQL swapi-graphql - A GraphQL schema and server wrapping swapi. graphql-server - GraphQL server with Mongoose (MongoDB) and Node.js. graphql-intro - https://medium.com/the-graphqlhub/your-first-graphql-server-3c766ab4f0a2 graphql-aws - Amazon AWS GraphQL API Server. graffiti-todo - Example Relay TodoMVC application using graffiti-mongoose. devknoll/gist:8b274f1c5d05230bfade UniversalRelayBoilerplate Boilerplate + examples for React Native (iOS, Android), React (isomorphic, Material-UI), Relay, GraphQL, JWT, Node.js, Apache Cassandra. vslinko/ripster relay-skeleton - React, Relay, GraphQL project skeleton simple-relay-starter - A very simple starter for React Relay using Browserify. relay-chat - an chat example showing Relay with routing and pagination. relay-todomvc - Relay TodoMVC with routing. graphql-express-sqlite - GraphQL server with Sqlite and Express koa-graphql-relay-example - Example of koa-graphql relay-fullstack - Relay Starter Kit integrated with Relay, GraphQL, Express, ES6/ES7, JSX, Webpack, Babel, Material Design Lite, and PostCSS. serverless-graphql-blog - A Serverless Blog leveraging GraphQL to offer a REST API with only 1 endpoint relay-cart - A simple shopping cart example leveraging relay & GraphQL with routing and pagination. graphql-loader - Example project to illustrate GraphQL, Express and Facebook DataLoader to connect to third party REST API swapi-graphql-lambda - A GraphQL schema hosted in AWS Lambda wrapping http://swapi.co/ Apollo Client documentation - Documentation and example for building GraphQL apps using apollo client Apollo Server tools, products, and libraries documentation - Documentation, tutorial and examples for building GraphQL server and connecting to SQL, MongoDB and REST endpoints. Apollo Link - The official guide for getting started with Apollo Link - a standard interface for modifying control flow of GraphQL requests and fetching GraphQL results. f8-apollo - Refactored version of the official F8 app of 2016, powered by React Native and the Apollo Stack. f8app - Source code of the official F8 app of 2016, powered by React Native and other Facebook open source projects. http://makeitopen.com Reindex Examples - Example projects for Reindex with using React Native and React.js for web. Modelizr Documentation - Documentation and Usage Examples for modelizr Vue Apollo Example - Apollo example project for Vue 2.0. angular2-graphql-rest - An example app with REST Api working side by side with GraphQL using Apollo Client with angular2-apollo. Includes step-by-step tutorial how to migrate from REST to GraphQL. GraphQL-DataLoader-Boilerplate - Boilerplate to start your GraphQL with DataLoader server GraphQL-CEP - Query address by CEP Apollo React example for Github GraphQL API - Usage Examples Apollo React for Github GraphQL API with create-react-app Intuitive GraphQL Resolver Example - GraphQL application example using RawModel.js. ReactQL starter kit - Universal React + Apollo + Redux + React Router 4, with SSR-enabled GraphQL, store (de/re)hydration and production code bundling. microhn - Simple Hacker News client built on top of GraphQLHub Apollo Web&Mobile Universal Starter Kit with Hot Code Reload - Apollo, GraphQL, React, React Native, Expo, Redux, Express, SQL and Twitter Bootstrap. Hot Code Reload of back end & front end using Webpack and Hot Module Replacement. Building Decoupled Sites and Apps with GraphQL and Next.js TypeScript Examples Basic Apollo Server - Basic Starter for Apollo Server, Using typescript and Webpack. Apollo Graphql Express Server - Minimal Apollo Graphql Express Server Prisma/Apollo/React Full-stack Example - An e-commerce example project with Prisma, GraphQL API Gateway, React, Apollo, Next.js, SSR, CI, and E2E testing. All TypeScript. Ruby Examples graphql-ruby-demo - Use graphql-ruby to expose a Rails app. github-graphql-rails-example - Example Rails app using GitHub's GraphQL API. relay-on-rails - Barebones starter kit for Relay application with Rails GraphQL server. relay-rails-blog - A graphql, relay and standard rails application powered demo weblog. to eat app - A sample graphql/rails/relay application with a related 3-part article series. Go Examples golang-relay-starter-kit - Barebones starting point for a Relay application with Golang GraphQL server. golang-graphql-playground - An example Golang GraphQL server written with graphql-go and graphql-relay-go. Try live demo at: http://golanggraphqlplayground-sogko.rhcloud.com todomvc-relay-go - Port of the React/Relay TodoMVC app, driven by a Golang GraphQL backend. Scala Examples sangria-akka-http-example - An example GraphQL server written with akka-http and sangria sangria-playground - An example of GraphQL server written with Play and sangria. Python Examples swapi-graphene - A GraphQL schema and server using Graphene - View demo online. Elixir Examples absinthe_example - Example usage of Absinthe GraphQL hello graphql phoenix - Examples of GraphQL Elixir Plug endpoints mounted in Phoenix - View demo online. PHP Examples Siler's GraphQL guide - A guide on how to build a PHP GraphQL endpoint. Laravel GraphQL - A sample integrating GraphQL with Laravel Adding a GraphQL API to your Symfony Flex application ReasonML Examples Todo list example - A todo list integrating GraphQL. Videos Zero-config Apollo + GraphQL with Apollo Boost Zero to GraphQL in 30 Minutes Data fetching for React applications at Facebook React Native & Relay: Bringing Modern Web Techniques to Mobile Exploring GraphQL Creating a GraphQL Server GraphQL at The Financial Times Relay: An Application Framework For React Building and Deploying Relay with Facebook Introduction to GraphQL Exploring GraphQL@Scale What's Next for Phoenix by Chris McCord GraphQL with Nick Schrock Build a GraphQL server for Node.js using PostgreSQL/MySQL GraphQL server tutorial for Node.js with SQL, MongoDB and REST JavaScript Air Episode 023: Transitioning from REST to GraphQL GraphQL Future at react-europe 2016 GraphQL at Facebook at react-europe 2016 Building native mobile apps with GraphQL at react-europe 2016 Blogs Official GraphQL blog Building Apollo Posts Using DataLoader to batch GraphQL requests Introducing Relay and GraphQL GraphQL Introduction Unofficial Relay FAQ Your First GraphQL Server GraphQL Overview - Getting Started with GraphQL and Node.js 4 Reasons you should try out GraphQL Moving from REST to GraphQL Writing a Basic API with GraphQL Start using GraphQL with Graffiti Building a GraphQL Server with Node.js and SQL GraphQL at The Financial Times Relay for visual learners Relay and Routing Learn Golang + GraphQL + Relay, Part 1: Your first Golang GraphQL server Learn Golang + GraphQL + Relay, Part 2: Your first Relay application From REST to GraphQL GraphQL: A data query language Subscriptions in GraphQL and Relay Relay 101: Building A Hacker News Client GraphQL Shorthand Notation Cheatsheet The GitHub GraphQL API Github GraphQL API React Example Testing a GraphQL Server using Jest How to implement viewerCanSee in GraphQL Introducing Yelp's Local Graph Sharing data in a Microservices Architecture using GraphQL Let's build a node.js GraphQL server for fetching Spotify REST API, in German | in English“Client-side only” realtime web applications with Firebase, GraphQL and apollo-client 2.0 Tutorials How to GraphQL - Fullstack Tutorial Website with Tracks for all Major Frameworks & Languages including React, Apollo, Relay, JavaScript, Ruby, Java, Elixir and many more learning-graphql - An attempt to learn GraphQL. Learn Relay - A comprehensive introduction to Relay Learn Apollo - A hands-on tutorial for Apollo GraphQL Client
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    November 24, 2021 Es6 Features lorem-ipsum React Interview Questions & Answers Table of Contents No. Questions Answer Core React false 1 What is React? false 2 What are the major features of React? false 3 What is JSX? false 4 What is the difference between Element and Component? false 5 How to create components in React? false 6 When to use a Class Component over a Function Component? false 7 What are Pure Components? false 8 What is state in React? false 9 What are props in React? false 10 What is the difference between state and props? false 11 Why should we not update the state directly? false 12 What is the purpose of callback function as an argument of setState()? false 13 What is the difference between HTML and React event handling? false 14 How to bind methods or event handlers in JSX callbacks? false 15 How to pass a parameter to an event handler or callback? false 16 What are synthetic events in React? false 17 What are inline conditional expressions? false 18 What is "key" prop and what is the benefit of using it in arrays of elements? false 19 What is the use of refs? false 20 How to create refs? false 21 What are forward refs? false 22 Which is preferred option with in callback refs and findDOMNode()? false 23 Why are String Refs legacy? false 24 What is Virtual DOM? false 25 How Virtual DOM works? false 26 What is the difference between Shadow DOM and Virtual DOM? false 27 What is React Fiber? false 28 What is the main goal of React Fiber? false 29 What are controlled components? false 30 What are uncontrolled components? false 31 What is the difference between createElement and cloneElement? false 32 What is Lifting State Up in React? false 33 What are the different phases of component lifecycle? false 34 What are the lifecycle methods of React? false 35 What are Higher-Order components? false 36 How to create props proxy for HOC component? false 37 What is context? false 38 What is children prop? false 39 How to write comments in React? false 40 What is the purpose of using super constructor with props argument? false 41 What is reconciliation? false 42 How to set state with a dynamic key name? false 43 What would be the common mistake of function being called every time the component renders? false 44 Is lazy function supports named exports? false 45 Why React uses className over class attribute? false 46 What are fragments? false 47 Why fragments are better than container divs? false 48 What are portals in React? false 49 What are stateless components? false 50 What are stateful components? false 51 How to apply validation on props in React? false 52 What are the advantages of React? false 53 What are the limitations of React? false 54 What are error boundaries in React v16 false 55 How error boundaries handled in React v15? false 56 What are the recommended ways for static type checking? false 57 What is the use of react-dom package? false 58 What is the purpose of render method of react-dom? false 59 What is ReactDOMServer? false 60 How to use InnerHtml in React? false 61 How to use styles in React? false 62 How events are different in React? false 63 What will happen if you use setState in constructor? false 64 What is the impact of indexes as keys? false 65 Is it good to use setState() in componentWillMount() method? false 66 What will happen if you use props in initial state? false 67 How do you conditionally render components? false 68 Why we need to be careful when spreading props on DOM elements?? false 69 How you use decorators in React? false 70 How do you memoize a component? false 71 How you implement Server-Side Rendering or SSR? false 72 How to enable production mode in React? false 73 What is CRA and its benefits? false 74 What is the lifecycle methods order in mounting? false 75 What are the lifecycle methods going to be deprecated in React v16? false 76 What is the purpose of getDerivedStateFromProps() lifecycle method? false 77 What is the purpose of getSnapshotBeforeUpdate() lifecycle method? false 78 Do Hooks replace render props and higher order components? false 79 What is the recommended way for naming components? false 80 What is the recommended ordering of methods in component class? false 81 What is a switching component? false 82 Why we need to pass a function to setState()? false 83 What is strict mode in React? false 84 What are React Mixins? false 85 Why is isMounted() an anti-pattern and what is the proper solution? false 86 What are the Pointer Events supported in React? false 87 Why should component names start with capital letter? false 88 Are custom DOM attributes supported in React v16? false 89 What is the difference between constructor and getInitialState? false 90 Can you force a component to re-render without calling setState? false 91 What is the difference between super() and super(props) in React using ES6 classes? false 92 How to loop inside JSX? false 93 How do you access props in attribute quotes? false 94 What is React PropType array with shape? false 95 How to conditionally apply class attributes? false 96 What is the difference between React and ReactDOM? false 97 Why ReactDOM is separated from React? false 98 How to use React label element? false 99 How to combine multiple inline style objects? false 100 How to re-render the view when the browser is resized? false 101 What is the difference between setState and replaceState methods? false 102 How to listen to state changes? false 103 What is the recommended approach of removing an array element in react state? false 104 Is it possible to use React without rendering HTML? false 105 How to pretty print JSON with React? false 106 Why you can't update props in React? false 107 How to focus an input element on page load? false 108 What are the possible ways of updating objects in state? false 110 How can we find the version of React at runtime in the browser? false 111 What are the approaches to include polyfills in your create-react-app? false 112 How to use https instead of http in create-react-app? false 113 How to avoid using relative path imports in create-react-app? false 114 How to add Google Analytics for react-router? false 115 How to update a component every second? false 116 How do you apply vendor prefixes to inline styles in React? false 117 How to import and export components using react and ES6? false 118 What are the exceptions on React component naming? false 119 Why is a component constructor called only once? false 120 How to define constants in React? false 121 How to programmatically trigger click event in React? false 122 Is it possible to use async/await in plain React? false 123 What are the common folder structures for React? false 124 What are the popular packages for animation? false 125 What is the benefit of styles modules? false 126 What are the popular React-specific linters? false 127 How to make AJAX call and In which component lifecycle methods should I make an AJAX call? false 128 What are render props? false React Router false 129 What is React Router? false 130 How React Router is different from history library? false 131 What are the <Router> components of React Router v4? false 132 What is the purpose of push and replace methods of history? false 133 How do you programmatically navigate using React router v4? false 134 How to get query parameters in React Router v4 false 135 Why you get "Router may have only one child element" warning? false 136 How to pass params to history.push method in React Router v4? false 137 How to implement default or NotFound page? false 138 How to get history on React Router v4? false 139 How to perform automatic redirect after login? false React Internationalization false 140 What is React-Intl? false 141 What are the main features of React Intl? false 142 What are the two ways of formatting in React Intl? false 143 How to use FormattedMessage as placeholder using React Intl? false 144 How to access current locale with React Intl false 145 How to format date using React Intl? false React Testing false 146 What is Shallow Renderer in React testing? false 147 What is TestRenderer package in React? false 148 What is the purpose of ReactTestUtils package? false 149 What is Jest? false 150 What are the advantages of Jest over Jasmine? false 151 Give a simple example of Jest test case false React Redux false 152 What is Flux? false 153 What is Redux? false 154 What are the core principles of Redux? false 155 What are the downsides of Redux compared to Flux? false 156 What is the difference between mapStateToProps() and mapDispatchToProps()? false 157 Can I dispatch an action in reducer? false 158 How to access Redux store outside a component? false 159 What are the drawbacks of MVW pattern false 160 Are there any similarities between Redux and RxJS? false 161 How to dispatch an action on load? false 162 How to use connect from React Redux? false 163 How to reset state in Redux? false 164 Whats the purpose of at symbol in the redux connect decorator? false 165 What is the difference between React context and React Redux? false 166 Why are Redux state functions called reducers? false 167 How to make AJAX request in Redux? false 168 Should I keep all component's state in Redux store? false 169 What is the proper way to access Redux store? false 170 What is the difference between component and container in React Redux? false 171 What is the purpose of the constants in Redux? false 172 What are the different ways to write mapDispatchToProps()? false 173 What is the use of the ownProps parameter in mapStateToProps() and mapDispatchToProps()? false 174 How to structure Redux top level directories? false 175 What is redux-saga? false 176 What is the mental model of redux-saga? false 177 What are the differences between call and put in redux-saga false 178 What is Redux Thunk? false 179 What are the differences between redux-saga and redux-thunk false 180 What is Redux DevTools? false 181 What are the features of Redux DevTools? false 182 What are Redux selectors and Why to use them? false 183 What is Redux Form? false 184 What are the main features of Redux Form? false 185 How to add multiple middlewares to Redux? false 186 How to set initial state in Redux? false 187 How Relay is different from Redux? false 188 What is an action in Redux? false React Native false 188 What is the difference between React Native and React? false 189 How to test React Native apps? false 190 How to do logging in React Native? false 191 How to debug your React Native? false React supported libraries and Integration false 192 What is reselect and how it works? false 193 What is Flow? false 194 What is the difference between Flow and PropTypes? false 195 How to use font-awesome icons in React? false 196 What is React Dev Tools? false 197 Why is DevTools not loading in Chrome for local files? false 198 How to use Polymer in React? false 199 What are the advantages of React over Vue.js? false 200 What is the difference between React and Angular? false 201 Why React tab is not showing up in DevTools? false 202 What are styled components? false 203 Give an example of Styled Components? false 204 What is Relay? false 205 How to use TypeScript in create-react-app application? false Miscellaneous false 206 What are the main features of reselect library? false 207 Give an example of reselect usage? false 209 Does the statics object work with ES6 classes in React? false 210 Can Redux only be used with React? false 211 Do you need to have a particular build tool to use Redux? false 212 How Redux Form initialValues get updated from state? false 213 How React PropTypes allow different type for one prop? false 214 Can I import an SVG file as react component? false 215 Why are inline ref callbacks or functions not recommended? false 216 What is render hijacking in React? false 217 What are HOC factory implementations? false 218 How to pass numbers to React component? false 219 Do I need to keep all my state into Redux? Should I ever use react internal state? false 220 What is the purpose of registerServiceWorker in React? false 221 What is React memo function? false 222 What is React lazy function? false 223 How to prevent unnecessary updates using setState? false 224 How do you render Array, Strings and Numbers in React 16 Version? false 225 How to use class field declarations syntax in React classes? false 226 What are hooks? false 227 What are the rules needs to follow for hooks? false 228 How to ensure hooks followed the rules in your project? false 229 What are the differences between Flux and Redux? false 230 What are the benefits of React Router V4? false 231 Can you describe about componentDidCatch lifecycle method signature? false 232 In which scenarios error boundaries do not catch errors? false 233 Why do you not need error boundaries for event handlers? false 234 What is the difference between try catch block and error boundaries? false 235 What is the behavior of uncaught errors in react 16? false 236 What is the proper placement for error boundaries? false 237 What is the benefit of component stack trace from error boundary? false 238 What is the required method to be defined for a class component? false 239 What are the possible return types of render method? false 240 What is the main purpose of constructor? false 241 Is it mandatory to define constructor for React component? false 242 What are default props? false 243 Why should not call setState in componentWillUnmount? false 244 What is the purpose of getDerivedStateFromError? false 245 What is the methods order when component re-rendered? false 246 What are the methods invoked during error handling? false 247 What is the purpose of displayName class property? false 248 What is the browser support for react applications? false 249 What is the purpose of unmountComponentAtNode method? false 250 What is code-splitting? false 251 What is the benefit of strict mode? false 252 What are Keyed Fragments? false 253 Does React support all HTML attributes? false 254 What are the limitations with HOCs? false 255 How to debug forwardRefs in DevTools? false 256 When component props defaults to true? false 257 What is NextJS and major features of it? false 258 How do you pass an event handler to a component? false 259 Is it good to use arrow functions in render methods? false 260 How to prevent a function from being called multiple times? false 261 How JSX prevents Injection Attacks? false 262 How do you update rendered elements? false 263 How do you say that props are read only? false 264 How do you say that state updates are merged? false 265 How do you pass arguments to an event handler? false 266 How to prevent component from rendering? false 267 What are the conditions to safely use the index as a key? false 268 Is it keys should be globally unique? false 269 What is the popular choice for form handling? false 270 What are the advantages of formik over redux form library? false 271 Why do you not required to use inheritance? false 272 Can I use web components in react application? false 273 What is dynamic import? false 274 What are loadable components? false 275 What is suspense component? false 276 What is route based code splitting? false 277 Give an example on How to use context? false 278 What is the purpose of default value in context? false 279 How do you use contextType? false 280 What is a consumer? false 281 How do you solve performance corner cases while using context? false 282 What is the purpose of forward ref in HOCs? false 283 Is it ref argument available for all functions or class components? false 284 Why do you need additional care for component libraries while using forward refs? false 285 How to create react class components without ES6? false 286 Is it possible to use react without JSX? false 287 What is diffing algorithm? false 288 What are the rules covered by diffing algorithm? false 289 When do you need to use refs? false 290 Is it prop must be named as render for render props? false 291 What are the problems of using render props with pure components? false 292 How do you create HOC using render props? false 293 What is windowing technique? false 294 How do you print falsy values in JSX? false 295 What is the typical use case of portals? false 296 How do you set default value for uncontrolled component? false 297 What is your favorite React stack? false 298 What is the difference between Real DOM and Virtual DOM? false 299 How to add Bootstrap to a react application? false 300 Can you list down top websites or applications using react as front end framework? false 301 Is it recommended to use CSS In JS technique in React? false 302 Do I need to rewrite all my class components with hooks? false 303 How to fetch data with React Hooks? false 304 Is Hooks cover all use cases for classes? false 305 What is the stable release for hooks support? false 306 Why do we use array destructuring (square brackets notation) in useState? false 307 What are the sources used for introducing hooks? false 308 How do you access imperative API of web components? false 309 What is formik? false 310 What are typical middleware choices for handling asynchronous calls in Redux? false 311 Do browsers understand JSX code? false 312 Describe about data flow in react? false 313 What is react scripts? false 314 What are the features of create react app? false 315 What is the purpose of renderToNodeStream method? false 316 What is MobX? false 317 What are the differences between Redux and MobX? false 318 Should I learn ES6 before learning ReactJS? false 319 What is Concurrent Rendering? false 320 What is the difference between async mode and concurrent mode? false 321 Can I use javascript urls in react16.9? false 322 What is the purpose of eslint plugin for hooks? false 323 What is the difference between Imperative and Declarative in React? false 324 What are the benefits of using typescript with reactjs? false 325 How do you make sure that user remains authenticated on page refresh while using Context API State Management? false 326 What are the benefits of new JSX transform? false 327 How does new JSX transform different from old transform? false 328 How do you get redux scaffolding using create-react-app? false 329 What are React Server components? false Inserting an item into an existing array Inserting an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or to the middle using splice. Those are known methods, but it doesn't mean there isn't a more performant way. Here we go: Adding an element at the end Adding an element at the end of the array is easy with push(), but it can be done in different ways. var arr = [1,2,3,4,5]; var arr2 = []; arr.push(6); arr[arr.length] = 6; arr2 = arr.concat([6]); Both first methods modify the original array. Don't believe me? Check the jsperf Performance on mobile : Android (v4.2.2) arr.push(6); and arr[arr.length] = 6; have the same performance // 3 319 694 ops/sec arr2 = arr.concat([6]); 50.61 % slower than the other two methods Chrome Mobile (v33.0.0) arr[arr.length] = 6; // 6 125 975 ops/sec arr.push(6); 66.74 % slower arr2 = arr.concat([6]); 87.63 % slower Safari Mobile (v9) arr[arr.length] = 6; // 7 452 898 ops/sec arr.push(6); 40.19 % slower arr2 = arr.concat([6]); 49.78 % slower Final victor 1. arr[arr.length] = 6; // with an average of 5 632 856 ops/sec 2. arr.push(6); // 35.64 % slower 3. arr2 = arr.concat([6]); // 62.67 % slower Performance on desktop Chrome (v48.0.2564) arr[arr.length] = 6; // 21 602 722 ops/sec arr.push(6); 61.94 % slower arr2 = arr.concat([6]); 87.45 % slower Firefox (v44) arr.push(6); // 56 032 805 ops/sec arr[arr.length] = 6; 0.52 % slower arr2 = arr.concat([6]); 87.36 % slower IE (v11) arr[arr.length] = 6; // 67 197 046 ops/sec arr.push(6); 39.61 % slower arr2 = arr.concat([6]); 93.41 % slower Opera (v35.0.2066.68) arr[arr.length] = 6; // 30 775 071 ops/sec arr.push(6); 71.60 % slower arr2 = arr.concat([6]); 83.70 % slower Safari (v9.0.3) arr.push(6); // 42 670 978 ops/sec arr[arr.length] = 6; 0.80 % slower arr2 = arr.concat([6]); 76.07 % slower Final victor 1. arr[arr.length] = 6; // with an average of 42 345 449 ops/sec 2. arr.push(6); // 34.66 % slower 3. arr2 = arr.concat([6]); // 85.79 % slower Add an element at the beginning Now if we are trying to add an item to the beginning of the array: var arr = [1,2,3,4,5]; arr.unshift(0); [0].concat(arr); Here is a little more detail: unshift edits the original array; concat returns a new array. jsperf Performance on mobile : Android (v4.2.2)[0].concat(arr); // 1 808 717 ops/sec arr.unshift(0); 97.85 % slower Chrome Mobile (v33.0.0)[0].concat(arr); // 1 269 498 ops/sec arr.unshift(0); 99.86 % slower Safari Mobile (v9) arr.unshift(0); // 3 250 184 ops/sec[0].concat(arr); 33.67 % slower Final victor 1. [0].concat(arr); // with an average of 4 972 622 ops/sec 2. arr.unshift(0); // 64.70 % slower Performance on desktop Chrome (v48.0.2564)[0].concat(arr); // 2 656 685 ops/sec arr.unshift(0); 96.77 % slower Firefox (v44)[0].concat(arr); // 8 039 759 ops/sec arr.unshift(0); 99.72 % slower IE (v11)[0].concat(arr); // 3 604 226 ops/sec arr.unshift(0); 98.31 % slower Opera (v35.0.2066.68)[0].concat(arr); // 4 102 128 ops/sec arr.unshift(0); 97.44 % slower Safari (v9.0.3) arr.unshift(0); // 12 356 477 ops/sec[0].concat(arr); 15.17 % slower Final victor 1. [0].concat(arr); // with an average of 6 032 573 ops/sec 2. arr.unshift(0); // 78.65 % slower Add an element in the middle Adding items in the middle of an array is easy with splice, and it's the most performant way to do it. var items = ['one', 'two', 'three', 'four']; items.splice(items.length / 2, 0, 'hello'); I tried to run these tests in various Browsers and OS and the results were similar. I hope these tips will be useful for you and encourage to perform your own tests! improve-nested-conditionals/- en - javascript How can we improve and make a more efficient nested if statement in javascript? if (color) { if (color === 'black') { printBlackBackground(); } else if (color === 'red') { printRedBackground(); } else if (color === 'blue') { printBlueBackground(); } else if (color === 'green') { printGreenBackground(); } else { printYellowBackground(); } } One way to improve the nested if statement would be using the switch statement. Although it is less verbose and is more ordered, it's not recommended to use it because it's so difficult to debug errors. Here's why. switch(color) { case 'black': printBlackBackground(); break; case 'red': printRedBackground(); break; case 'blue': printBlueBackground(); break; case 'green': printGreenBackground(); break; default: printYellowBackground(); } But what if we have a conditional with several checks in each statement? In this case, if we want it less verbose and more ordered, we can use the conditional switch. If we pass true as a parameter to the switch statement, it allows us to put a conditional in each case. switch(true) { case (typeof color === 'string' && color === 'black'): printBlackBackground(); break; case (typeof color === 'string' && color === 'red'): printRedBackground(); break; case (typeof color === 'string' && color === 'blue'): printBlueBackground(); break; case (typeof color === 'string' && color === 'green'): printGreenBackground(); break; case (typeof color === 'string' && color === 'yellow'): printYellowBackground(); break; } If refactoring is an option, we can try to simplify the functions themselves. For example instead of having a function for each background color we could have an function that takes the color as an argument. function printBackground(color) { if (!color || typeof color !== 'string') { return; // Invalid color, return immediately } } But if refactoring is not an option, we must always avoid having several checks in every condition and avoid using switch as much as possible. We also must take into account that the most efficient way to do this is through an object. var colorObj = { 'black': printBlackBackground, 'red': printRedBackground, 'blue': printBlueBackground, 'green': printGreenBackground, 'yellow': printYellowBackground }; if (color in colorObj) { colorObj[color](); } Here you can find more information about this. sorting-strings-with-accented-characters/- en - javascript Javascript has a native method sort that allows sorting arrays. Doing a simple array.sort() will treat each array entry as a string and sort it alphabetically. Also you can provide your own custom sorting function.['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort(); // ["Buenos Aires", "Mumbai", "New York", "Shanghai"] But when you try order an array of non ASCII characters like this ['é', 'a', 'ú', 'c'], you will obtain a strange result ['c', 'e', 'á', 'ú']. That happens because sort works only with the English language. See the next example:// Spanish ['único','árbol', 'cosas', 'fútbol'].sort(); // ["cosas", "fútbol", "árbol", "único"] // bad order // German ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); // ["Wann", "Woche", "wäre", "wöchentlich"] // bad order Fortunately, there are two ways to overcome this behavior localeCompare and Intl.Collator provided by ECMAScript Internationalization API. Both methods have their own custom parameters in order to configure it to work adequately. Using localeCompare()['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) { return a.localeCompare(b); }); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) { return a.localeCompare(b); }); // ["Wann", "wäre", "Woche", "wöchentlich"] Using Intl.Collator()['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare); // ["árbol", "cosas", "fútbol", "único"] ['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare); // ["Wann", "wäre", "Woche", "wöchentlich"] For each method you can customize the location. According to Firefox Intl.Collator is faster when comparing large numbers of strings. So when you are working with arrays of strings in a language other than English, remember to use this method to avoid unexpected sorting. differences-between-undefined-and-null/- en - javascript undefined means a variable has not been declared, or has been declared but has not yet been assigned a value null is an assignment value that means "no value" Javascript sets unassigned variables with a default value of undefined Javascript never sets a value to null. It is used by programmers to indicate that a var has no value. undefined is not valid in JSON while null is undefined typeof is undefined null typeof is an object. Why? Both are primitives Both are falsy ( Boolean(undefined) // false, Boolean(null) // false) You can know if a variable is undefined typeof variable === "undefined" - You can check if a variable is [null](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null) ```javascript variable === null The equality operator considers them equal, but the identity doesn't null == undefined // true null === undefined // false --- # writing-a-single-method-for-arrays-and-a-single-element/ - en - javascript --- Rather than writing separate methods to handle an array and a single element parameter, write your functions so they can handle both. This is similar to how some of jQuery's functions work (`css` will modify everything matched by the selector). You just have to concat everything into an array first. `Array.concat` will accept an array or a single element. ```javascript function printUpperCase(words) { var elements = [].concat(words || []); for (var i = 0; i < elements.length; i++) { console.log(elements[i].toUpperCase()); } } printUpperCase is now ready to accept a single node or an array of nodes as its parameter. It also avoids the potential TypeError that would be thrown if no parameter was passed. printUpperCase("cactus"); // => CACTUS printUpperCase(["cactus", "bear", "potato"]); // => CACTUS // BEAR // POTATO use-strict-and-get-lazy/- en - javascript Strict-mode JavaScript makes it easier for the developer to write "secure" JavaScript. By default, JavaScript allows the programmer to be pretty careless, for example, by not requiring us to declare our variables with "var" when we first introduce them. While this may seem like a convenience to the unseasoned developer, it's also the source of many errors when a variable name is misspelled or accidentally referred to out of its scope. Programmers like to make the computer do the boring stuff for us, and automatically check our work for mistakes. That's what the JavaScript "use strict" directive allows us to do, by turning our mistakes into JavaScript errors. We add this directive either by adding it at the top of a js file:// Whole-script strict mode syntax "use strict"; var v = "Hi! I'm a strict mode script!"; or inside a function: function f() { // Function-level strict mode syntax 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); } function f2() { return "I'm not strict."; } By including this directive in a JavaScript file or function, we will direct the JavaScript engine to execute in strict mode which disables a bunch of behaviors that are usually undesirable in larger JavaScript projects. Among other things, strict mode changes the following behaviors: Variables can only be introduced when they are preceded with "var" Attempting to write to read-only properties generates a noisy error You have to call constructors with the "new" keyword"this" is not implicitly bound to the global object Very limited use of eval() allowed Protects you from using reserved words or future reserved words as variable names Strict mode is great for new projects, but can be challenging to introduce into older projects that don't already use it in most places. It also can be problematic if your build chain concatenates all your js files into one big file, as this may cause all files to execute in strict mode. It is not a statement, but a literal expression, ignored by earlier versions of JavaScript. Strict mode is supported in: Internet Explorer from version 10. Firefox from version 4. Chrome from version 13. Safari from version 5.1. Opera from version 12. See MDN for a fuller description of strict mode. converting-a-node-list-to-an-array/- en - javascript The querySelectorAll method returns an array-like object called a node list. These data structures are referred to as "Array-like", because they appear as an array, but can not be used with array methods like map and forEach. Here's a quick, safe, and reusable way to convert a node list into an array of DOM elements: const nodelist = document.querySelectorAll('div'); const nodelistToArray = Array.apply(null, nodelist); //later on .. nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); //etc... The apply method is used to pass an array of arguments to a function with a given this value. MDN states that apply will take an array-like object, which is exactly what querySelectorAll returns. Since we don't need to specify a value for this in the context of the function, we pass in null or 0. The result is an actual array of DOM elements which contains all of the available array methods. Alternatively you can use Array.prototype.slice combined with Function.prototype.call or Function.prototype.apply passing the array-like object as the value of this: const nodelist = document.querySelectorAll('div'); const nodelistToArray = Array.prototype.slice.call(nodelist); // or equivalently Array.prototype.slice.apply(nodelist); //later on .. nodelistToArray.forEach(...); nodelistToArray.map(...); nodelistToArray.slice(...); //etc... Or if you are using ES2015 you can use the spread operator ... const nodelist = [...document.querySelectorAll('div')]; // returns a real array //later on .. nodelist.forEach(...); nodelist.map(...); nodelist.slice(...); //etc... template-strings/- en - javascript As of ES6, JS now has template strings as an alternative to the classic end quotes strings. Ex: Normal string var firstName = 'Jake'; var lastName = 'Rawr'; console.log('My name is ' + firstName + ' ' + lastName); // My name is Jake Rawr Template String var firstName = 'Jake'; var lastName = 'Rawr'; console.log(`My name is ${firstName} ${lastName}`); // My name is Jake Rawr You can do multi-line strings without , perform simple logic (ie 2+3) or even use the ternary operator inside ${} in template strings. var val1 = 1, val2 = 2; console.log(`${val1} is ${val1 < val2 ? 'less than': 'greater than'} ${val2}`) // 1 is less than 2 You are also able to modify the output of template strings using a function; they are called tagged template strings for example usages of tagged template strings. You may also want to read to understand template strings more. check-if-a-property-is-in-a-object/- en - javascript When you have to check if a property is present in an object, you probably are doing something like this: var myObject = { name: '@tips_js' }; if (myObject.name) { ... } That's ok, but you have to know that there are two native ways for this kind of thing, the in operator and Object.hasOwnProperty. Every object descended from Object, has both ways available. See the big Difference var myObject = { name: '@tips_js' }; myObject.hasOwnProperty('name'); // true 'name' in myObject; // true myObject.hasOwnProperty('valueOf'); // false, valueOf is inherited from the prototype chain 'valueOf' in myObject; // true Both differ in the depth at which they check the properties. In other words, hasOwnProperty will only return true if key is available on that object directly. However, the in operator doesn't discriminate between properties created on an object and properties inherited from the prototype chain. Here's another example: var myFunc = function() { this.name = '@tips_js'; }; myFunc.prototype.age = '10 days'; var user = new myFunc(); user.hasOwnProperty('name'); // true user.hasOwnProperty('age'); // false, because age is from the prototype chain Check the live examples here! I also recommend reading this discussion about common mistakes made when checking a property's existence in objects. hoisting/- en - javascript Understanding hoisting will help you organize your function scope. Just remember, variable declarations and function definitions are hoisted to the top. Variable definitions are not, even if you declare and define a variable on the same line. Also, a variable declaration lets the system know that the variable exists while definition assigns it a value. function doTheThing() { // ReferenceError: notDeclared is not defined console.log(notDeclared); // Outputs: undefined console.log(definedLater); var definedLater; definedLater = 'I am defined!' // Outputs: 'I am defined!' console.log(definedLater) // Outputs: undefined console.log(definedSimulateneously); var definedSimulateneously = 'I am defined!' // Outputs: 'I am defined!' console.log(definedSimulateneously) // Outputs: 'I did it!' doSomethingElse(); function doSomethingElse(){ console.log('I did it!'); } // TypeError: undefined is not a function functionVar(); var functionVar = function(){ console.log('I did it!'); } } To make things easier to read, declare all of your variables at the top of your function scope so it is clear which scope the variables are coming from. Define your variables before you need to use them. Define your functions at the bottom of your scope to keep them out of your way. pseudomandatory-parameters-in-es6-functions/- en - javascript In many programming languages the parameters of a function are by default mandatory and the developer has to explicitly define that a parameter is optional. In Javascript, every parameter is optional, but we can enforce this behavior without messing with the actual body of a function, taking advantage of [ es6's default values for parameters] ( http://exploringjs.com/es6/ch\_parameter-handling.html#sec\_parameter-default-values) feature. const _err = function( message ){ throw new Error( message ); } const getSum = (a = _err('a is not defined'), b = _err('b is not defined')) => a + b getSum( 10 ) // throws Error, b is not defined getSum( undefined, 10 ) // throws Error, a is not defined _err is a function that immediately throws an Error. If no value is passed for one of the parameters, the default value is going to be used, _err will be called and an Error will be thrown. You can see more examples for the default parameters feature on Mozilla's Developer Network tip-to-measure-performance-of-a-javascript-block/- en - javascript For quickly measuring performance of a javascript block, we can use the console functions like console.time(label) and console.timeEnd(label) console.time("Array initialize"); var arr = new Array(100), len = arr.length, i; for (i = 0; i < len; i++) { arr[i] = new Object(); }; console.timeEnd("Array initialize"); // Outputs: Array initialize: 0.711ms More info: Console object, Javascript benchmarking Demo: jsfiddle - codepen (outputs in browser console) Note: As Mozilla suggested don't use this for production sites, use it for development purposes only. fat-arrow-functions/- en - javascript Introduced as a new feature in ES6, fat arrow functions may come as a handy tool to write more code in fewer lines. The name comes from its syntax, =>, which is a 'fat arrow', as compared to a thin arrow ->. Some programmers might already know this type of function from different languages such as Haskell, as 'lambda expressions', or as 'anonymous functions'. It is called anonymous, as these arrow functions do not have a descriptive function name. What are the benefits? Syntax: fewer LOC; no more typing function keyword over and over again Semantics: capturing the keyword this from the surrounding context Simple syntax example Have a look at these two code snippets, which do the exact same job, and you will quickly understand what fat arrow functions do:// general syntax for fat arrow functions param => expression // may also be written with parentheses // parentheses are required on multiple params (param1 [, param2]) => expression // using functions var arr = [5,3,2,9,1]; var arrFunc = arr.map(function(x) { return x * x; }); console.log(arr) // using fat arrow var arr = [5,3,2,9,1]; var arrFunc = arr.map((x) => x*x); console.log(arr) As you can see, the fat arrow function in this case can save you time typing out the parentheses as well as the function and return keywords. I would advise you to always write parentheses around the parameter inputs, as the parentheses will be needed for multiple input parameters, such as in (x,y) => x+y. It is just a way to cope with forgetting them in different use cases. But the code above would also work like this: x => x*x. So far, these are only syntactical improvements, which lead to fewer LOC and better readability. Lexically binding this There is another good reason to use fat arrow functions. There is the issue with the context of this. With arrow functions, you don't need to worry about .bind(this) or setting that = this anymore, as fat arrow functions pick the context of this from the lexical surrounding. Have a look at the next [example] ( https://jsfiddle.net/pklinger/rw94oc11/):// globally defined this.i this.i = 100; var counterA = new CounterA(); var counterB = new CounterB(); var counterC = new CounterC(); var counterD = new CounterD(); // bad example function CounterA() { // CounterA's `this` instance (!! gets ignored here) this.i = 0; setInterval(function () { // `this` refers to global object, not to CounterA's `this` // therefore starts counting with 100, not with 0 (local this.i) this.i++; document.getElementById("counterA").innerHTML = this.i; }, 500); } // manually binding that = this function CounterB() { this.i = 0; var that = this; setInterval(function() { that.i++; document.getElementById("counterB").innerHTML = that.i; }, 500); } // using .bind(this) function CounterC() { this.i = 0; setInterval(function() { this.i++; document.getElementById("counterC").innerHTML = this.i; }.bind(this), 500); } // fat arrow function function CounterD() { this.i = 0; setInterval(() => { this.i++; document.getElementById("counterD").innerHTML = this.i; }, 500); } Further information about fat arrow functions may be found at [MDN] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow\_functions). To see different syntax options visit [this site] ( http://jsrocks.org/2014/10/arrow-functions-and-their-scope/). even-simpler-way-of-using-indexof-as-a-contains-clause/- en - javascript JavaScript by default does not have a contains method. And for checking existence of a substring in a string or an item in an array you may do this: var someText = 'javascript rules'; if (someText.indexOf('javascript') !== -1) { } // or if (someText.indexOf('javascript') >= 0) { } But let's look at these Expressjs code snippets. examples/mvc/lib/boot.js for (var key in obj) { // "reserved" exports if (~['name', 'prefix', 'engine', 'before'].indexOf(key)) continue; lib/utils.js exports.normalizeType = function(type){ return ~type.indexOf('/') ? acceptParams(type) : { value: mime.lookup(type), params: {} }; }; examples/web-service/index.js// key is invalid if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key')); The gotcha is the bitwise operator ~, "Bitwise operators perform their operations on binary representations, but they return standard JavaScript numerical values." It transforms -1 into 0, and 0 evaluates to false in JavaScript: var someText = 'text'; !!~someText.indexOf('tex'); // someText contains "tex" - true !~someText.indexOf('tex'); // someText NOT contains "tex" - false ~someText.indexOf('asd'); // someText doesn't contain "asd" - false ~someText.indexOf('ext'); // someText contains "ext" - true String.prototype.includes() ES6 introduced the includes() method and you can use it to determine whether or not a string includes another string:'something'.includes('thing'); // true With ECMAScript 2016 (ES7) it is even possible to use these techniques with Arrays:!!~[1, 2, 3].indexOf(1); // true [1, 2, 3].includes(1); // true Unfortunately, it is only supported in Chrome, Firefox, Safari 9 or above and Edge; not IE11 or lower. It's better used in controlled environments. passing-arguments-to-callback-functions/- en - javascript By default you cannot pass arguments to a callback function. For example: function callback() { console.log('Hi human'); } document.getElementById('someelem').addEventListener('click', callback); You can take advantage of the closure scope in Javascript to pass arguments to callback functions. Check this example: function callback(a, b) { return function() { console.log('sum = ', (a+b)); } } var x = 1, y = 2; document.getElementById('someelem').addEventListener('click', callback(x, y)); What are closures? Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created. Check MDN Documentation to learn more. So this way the arguments x and y are in scope of the callback function when it is called. Another method to do this is using the bind method. For example: var alertText = function(text) { alert(text); }; document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello')); There is a very slight difference in performance of both methods, checkout jsperf. nodejs-run-a-module-if-it-is-not-required/- en - javascript In node, you can tell your program to do two different things depending on whether the code is run from require('./something.js') or node something.js. This is useful if you want to interact with one of your modules independently. if (!module.parent) { // ran with `node something.js` app.listen(8088, function() { console.log('app listening on port 8088'); }) } else { // used with `require('/.something.js')` module.exports = app; } See the documentation for modules for more info. rounding-the-fast-way/- en - javascript This tip is about performance...with a hidden price tag. Have you ever come across the double tilde ~~ operator? It's also often called the "double bitwise NOT" operator. You can often use it as a faster substitute for Math.trunc(). Why is that? One bitwise shift ~ first truncates input to 32 bits, then transforms it into -(input+1). The double bitwise shift therefore transforms the input into -(-(input + 1)+1) making it a great tool to round towards zero. For numeric input, it therefore mimics Math.trunc(). On failure, 0 is returned, which might come in handy sometimes instead of Math.trunc(), which returns NaN on failure.// single ~ console.log(~1337) // -1338 // numeric input console.log(~~47.11) // -> 47 console.log(~~1.9999) // -> 1 console.log(~~3) // -> 3 However, while ~~ is probably a better performer, experienced programmers often stick with Math.trunc() instead. To understand why, here's a clinical view on this operator. INDICATIONS When every CPU cycle counts~~ is probably faster than Math.trunc() across the board, though you should test that assumption on whichever platforms matter to you. Also, you'd generally have to perform millions of such operations to have any visible impact at run time. When code clarity is not a concern If you're trying to confuse others, or get maximum utility from your minifier/uglifier, this is a relatively cheap way to do it. CONTRAINDICATIONS When your code needs to be maintained Code clarity is of great importance in the long term, whether you work in a team, contribute to public code repos, or fly solo. As the oft-quoted saying goes: Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live. For a solo programmer, that psychopath is inevitably "you in six months". When you forget that ~~ always rounds to zero Newbie programmers may fixate on the cleverness of ~~, forgetting the significance of "just drop the fractional portion of this number". This can easily lead to fencepost errors (a.k.a. "off-by-one") when transforming floats to array indices or related ordinal values, where a different kind of fractional rounding may actually be called for. (Lack of code clarity usually contributes to this problem.) For instance, if you're counting numbers on a "nearest integer" basis, you should use Math.round() instead of ~~, but programmer laziness and the impact of 10 whole characters saved per use on human fingers often triumph over cold logic, leading to incorrect results. In contrast, the very names of the Math.xyz() functions clearly communicate their effect, reducing the probability of accidental errors. When dealing with large-magnitude numbers Because ~ first does a 32-bit conversion, ~~ results in bogus values around ±2.15 billion. If you don't properly range-check your input, a user could trigger unexpected behavior when the transformed value ends up being a great distance from the original: a = 2147483647.123 // maximum positive 32-bit integer, plus a bit more console.log(~~a) // -> 2147483647 (ok) a += 10000 // -> 2147493647.123 (ok) console.log(~~a) // -> -2147483648 (huh?) One particularly vulnerable area involves dealing with Unix epoch timestamps (measured in seconds from 1 Jan 1970 00:00:00 UTC). A quick way to get such values is: epoch_int = ~~(+new Date() / 1000) // Date() epochs in milliseconds, so we scale accordingly However, when dealing with timestamps after 19 Jan 2038 03:14:07 UTC (sometimes called the Y2038 limit), this breaks horribly:// epoch timestamp for 1 Jan 2040 00:00:00.123 UTC epoch = +new Date('2040-01-01') / 1000 + 0.123 // -> 2208988800.123 // back to the future! epoch_int = ~~epoch // -> -2085978496 console.log(new Date(epoch_int * 1000)) // -> Wed Nov 25 1903 17:31:44 UTC // that was fun, now let's get real epoch_flr = Math.floor(epoch) // -> 2208988800 console.log(new Date(epoch_flr * 1000)) // -> Sun Jan 01 2040 00:00:00 UTC When the original input wasn't sanitized Because ~~ transforms every non-number into 0: console.log(~~[]) // -> 0 console.log(~~NaN) // -> 0 console.log(~~null) // -> 0 some programmers treat it as alternative to proper input validation. However, this can lead to strange logic bugs down the line, since you're no longer distinguishing between invalid inputs and actual 0 values. This is therefore not a recommended practice. When so many people think ~~X == Math.floor(X) Most people who write about "double bitwise NOT" incorrectly equate it with Math.floor() for some reason. If you can't write about it accurately, odds are good you'll eventually misuse it. Others are more careful to mention Math.floor() for positive inputs and Math.ceil() for negative ones, but that forces you to stop and think about the values you're dealing with. This defeats the purpose of ~~ as a handy no-gotchas shortcut. DOSAGE Avoid where possible. Use sparingly otherwise. ADMINISTRATION Apply cautiously. Sanitize values before applying. Carefully document relevant assumptions about the values being transformed. Review code to deal with, at minimum: logic bugs where invalid inputs are instead passed to other code modules as valid 0 values range errors on transformed inputs fencepost errors due to incorrect rounding direction safe-string-concatenation/- en - javascript Suppose you have a couple of variables with unknown types and you want to concatenate them in a string. To be sure that the arithmetical operation is not be applied during concatenation, use concat: var one = 1; var two = 2; var three = '3'; var result = ''.concat(one, two, three); //"123" This way of concatenting does exactly what you'd expect. In contrast, concatenation with pluses might lead to unexpected results: var one = 1; var two = 2; var three = '3'; var result = one + two + three; //"33" instead of "123" Speaking about performance, compared to the join type of concatenation, the speed of concat is pretty much the same. You can read more about the concat function on MDN page. return-objects-to-enable-chaining-of-functions/- en - javascript When creating functions on an object in Object Oriented Javascript, returning the object in the function will enable you to chain functions together. function Person(name) { this.name = name; this.sayName = function() { console.log("Hello my name is: ", this.name); return this; }; this.changeName = function(name) { this.name = name; return this; }; } var person = new Person("John"); person.sayName().changeName("Timmy").sayName(); shuffle-an-array/- en - javascript This snippet here uses Fisher-Yates Shuffling Algorithm to shuffle a given array. function shuffle(arr) { var i, j, temp; for (i = arr.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } return arr; }; An example: var a = [1, 2, 3, 4, 5, 6, 7, 8]; var b = shuffle(a); console.log(b); // [2, 7, 8, 6, 5, 3, 1, 4] two-ways-to-empty-an-array/- en - javascript You define an array and want to empty its contents. Usually, you would do it like this:// define Array var list = [1, 2, 3, 4]; function empty() { //empty your array list = []; } empty(); But there is another way to empty an array that is more performant. You should use code like this: var list = [1, 2, 3, 4]; function empty() { //empty your array list.length = 0; } empty(); list = [] assigns a reference to a new array to a variable, while any other references are unaffected. which means that references to the contents of the previous array are still kept in memory, leading to memory leaks. list.length = 0 deletes everything in the array, which does hit other references. In other words, if you have two references to the same array ( a = [1,2,3]; a2 = a;), and you delete the array's contents using list.length = 0, both references (a and a2) will now point to the same empty array. (So don't use this technique if you don't want a2 to hold an empty array!) Think about what this will output: var foo = [1,2,3]; var bar = [1,2,3]; var foo2 = foo; var bar2 = bar; foo = []; bar.length = 0; console.log(foo, bar, foo2, bar2); // [] [] [1, 2, 3] [] Stackoverflow more detail: difference-between-array-length-0-and-array converting-to-number-fast-way/- en - javascript Converting strings to numbers is extremely common. The easiest and fastest ( jsPerf) way to achieve that would be using the + (plus) operator. var one = '1'; var numberOne = +one; // Number 1 You can also use the - (minus) operator which type-converts the value into number but also negates it. var one = '1'; var negativeNumberOne = -one; // Number -1 use_=== instead\ of_==/- en - javascript The == (or !=) operator performs an automatic type conversion if needed. The === (or !==) operator will not perform any conversion. It compares the value and the type, which could be considered faster ( jsPref) than ==.[10] == 10 // is true [10] === 10 // is false '10' == 10 // is true '10' === 10 // is false [] == 0 // is true [] === 0 // is false '' == false // is true but true == "a" is false '' === false // is false Using-immediately-invoked-function-expression/- en - javascript Called as "Iffy" ( IIFE - immediately invoked function expression) is an anonymous function expression that is immediately invoked and has some important uses in Javascript.(function() { // Do something​ } )() It is an anonymous function expression that is immediately invoked, and it has some particularly important uses in JavaScript. The pair of parenthesis surrounding the anonymous function turns the anonymous function into a function expression or variable expression. So instead of a simple anonymous function in the global scope, or wherever it was defined, we now have an unnamed function expression. Similarly, we can even create a named, immediately invoked function expression:(someNamedFunction = function(msg) { console.log(msg || "Nothing for today !!") }) (); // Output --> Nothing for today !!​ ​ someNamedFunction("Javascript rocks !!"); // Output --> Javascript rocks !! someNamedFunction(); // Output --> Nothing for today !!​ For more details, check the following URL's - Link 1 Link 2 Performance: jsPerf c filtering-and-sorting-a-list-of-strings/- en - javascript You may have a big list of names you need to filter in order to remove duplicates and sort them alphabetically. In our example we are going to use the list of JavaScript reserved keywords we can find across the different versions of the language, but as you can notice, there is a lot of duplicated keywords and they are not alphabetically organized. So this is a perfect list ( Array) of strings to test out this JavaScript tip. var keywords = ['do', 'if', 'in', 'for', 'new', 'try', 'var', 'case', 'else', 'enum', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'delete', 'export', 'import', 'return', 'switch', 'typeof', 'default', 'extends', 'finally', 'continue', 'debugger', 'function', 'do', 'if', 'in', 'for', 'int', 'new', 'try', 'var', 'byte', 'case', 'char', 'else', 'enum', 'goto', 'long', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'final', 'float', 'short', 'super', 'throw', 'while', 'delete', 'double', 'export', 'import', 'native', 'public', 'return', 'static', 'switch', 'throws', 'typeof', 'boolean', 'default', 'extends', 'finally', 'package', 'private', 'abstract', 'continue', 'debugger', 'function', 'volatile', 'interface', 'protected', 'transient', 'implements', 'instanceof', 'synchronized', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof', 'do', 'if', 'in', 'for', 'let', 'new', 'try', 'var', 'case', 'else', 'enum', 'eval', 'null', 'this', 'true', 'void', 'with', 'await', 'break', 'catch', 'class', 'const', 'false', 'super', 'throw', 'while', 'yield', 'delete', 'export', 'import', 'public', 'return', 'static', 'switch', 'typeof', 'default', 'extends', 'finally', 'package', 'private', 'continue', 'debugger', 'function', 'arguments', 'interface', 'protected', 'implements', 'instanceof']; Since we don't want to change our original list, we are going to use a high order function named filter, which will return a new filter array based in a predicate ( function) we pass to it. The predicate will compare the index of the current keyword in the original list with its index in the new list and will push it to the new array only if the indexes match. Finally we are going to sort the filtered list using the sort function which takes a comparison function as the only argument, returning a alphabetically sorted list. var filteredAndSortedKeywords = keywords .filter(function (keyword, index) { return keywords.lastIndexOf(keyword) === index; }) .sort(function (a, b) { return a < b ? -1 : 1; }); The ES6 (ECMAScript 2015) version using arrow functions looks a little simpler: const filteredAndSortedKeywords = keywords .filter((keyword, index) => keywords.lastIndexOf(keyword) === index) .sort((a, b) => a < b ? -1 : 1); And this is the final filtered and sorted list of JavaScript reserved keywords: console.log(filteredAndSortedKeywords); // ['abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final', 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import', 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new', 'null', 'package', 'private', 'protected', 'public', 'return', 'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while', 'with', 'yield'] Thanks to _[@nikshulipa]( https://github.com/nikshulipa), [@kirilloid]( https://twitter.com/kirilloid), [@lesterzone]( https://twitter.com/lesterzone), [@tracker1]( https://twitter.com/tracker1), [@manuel_del_pozo]( https://twitter.com/manuel\ del_pozo)_ for all the comments and suggestions!_ short-circuit-evaluation-in-js/- en - javascript Short-circuit evaluation says, the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first argument of the AND (&&) function evaluates to false, the overall value must be false; and when the first argument of the OR (||) function evaluates to true, the overall value must be true. For the following test condition and isTrue and isFalse function. var test = true; var isTrue = function(){ console.log('Test is true.'); }; var isFalse = function(){ console.log('Test is false.'); }; Using logical AND - &&.// A normal if statement. if(test){ isTrue(); // Test is true } // Above can be done using '&&' as - ( test && isTrue() ); // Test is true Using logical OR - ||. test = false; if(!test){ isFalse(); // Test is false. } ( test || isFalse()); // Test is false. The logical OR could also be used to set a default value for function argument. function theSameOldFoo(name){ name = name || 'Bar' ; console.log("My best friend's name is " + name); } theSameOldFoo(); // My best friend's name is Bar theSameOldFoo('Bhaskar'); // My best friend's name is Bhaskar The logical AND could be used to avoid exceptions when using properties of undefined. Example: var dog = { bark: function(){ console.log('Woof Woof'); } }; // Calling dog.bark(); dog.bark(); // Woof Woof. // But if dog is not defined, dog.bark() will raise an error "Cannot read property 'bark' of undefined." // To prevent this, we can use &&. dog&&dog.bark(); // This will only call dog.bark(), if dog is defined. curry-vs-partial-application/- en - javascript Currying Currying takes a function f: X * Y -> R and turns it into a function f': X -> (Y -> R) Instead of calling f with two arguments, we invoke f' with the first argument. The result is a function that we then call with the second argument to produce the result. Thus, if the uncurried f is invoked as f(3,5) then the curried f' is invoked as f(3)(5) For example: Uncurried add() function add(x, y) { return x + y; } add(3, 5); // returns 8 Curried add() function addC(x) { return function (y) { return x + y; } } addC(3)(5); // returns 8 The algorithm for currying. Curry takes a binary function and returns a unary function that returns a unary function. curry: (X × Y → R) → (X → (Y → R)) Javascript Code: function curry(f) { return function(x) { return function(y) { return f(x, y); } } } Partial application Partial application takes a function f: X * Y -> R and a fixed value for the first argument to produce a new function f`: Y -> R f' does the same as f, but only has to fill in the second parameter which is why its arity is one less than the arity of f. For example: Binding the first argument of function add to 5 produces the function plus5. function plus5(y) { return 5 + y; } plus5(3); // returns 8 The algorithm of partial application.* partApply takes a binary function and a value and produces a unary function. partApply : ((X × Y → R) × X) → (Y → R) Javascript Code: function partApply(f, x) { return function(y) { return f(x, y); } } speed-up-recursive-functions-with-memoization/- en - javascript Fibonacci sequence is very familiar to everybody. We can write the following function in 20 seconds. var fibonacci = function(n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); } It works, but is not efficient. It did lots of duplicate computing works, we can cache its previously computed results to speed it up. var fibonacci = (function() { var cache = [0, 1]; // cache the value at the n index return function(n) { if (cache[n] === undefined) { for (var i = cache.length; i <= n; ++i) { cache[i] = cache[i - 1] + cache[i - 2]; } } return cache[n]; } })(); Also, we can define a higher-order function that accepts a function as its argument and returns a memoized version of the function. var memoize = function(func) { var cache = {}; return function() { var key = JSON.stringify(Array.prototype.slice.call(arguments)); return key in cache ? cache[key] : (cache[key] = func.apply(this, arguments)); } } fibonacci = memoize(fibonacci); And this is an ES6 version of the memoize function. var memoize = function(func) { const cache = {}; return (...args) => { const key = JSON.stringify(args); return key in cache ? cache[key] : (cache[key] = func(...args)); } } fibonacci = memoize(fibonacci); we can use memoize() in many other situations GCD(Greatest Common Divisor) var gcd = memoize(function(a, b) { var t; if (a < b) t = b, b = a, a = t; while (b != 0) t = b, b = a % b, a = t; return a; }); gcd(27, 183); //=> 3 Factorial calculation var factorial = memoize(function(n) { return (n <= 1) ? 1 : n * factorial(n - 1); }) factorial(5); //=> 120 Learn more about memoization: Memoization - Wikipedia Implementing Memoization in JavaScript converting-truthy-falsy-values-to-boolean/- en - javascript You can convert a truthy or falsy value to true boolean with the !! operator.!!"" // false !!0 // false !!null // false !!undefined // false !!NaN // false !!"hello" // true !!1 // true !!{} // true !![] // true avoid-modifying-or-passing-arguments-into-other-functions-it-kills-optimization/- en - javascript ###Background Within JavaScript functions, the variable name arguments lets you access all of the arguments passed to the function. arguments is an array-like object; arguments can be accessed using array notation, and it has the length property, but it doesn't have many of the built-in methods that arrays have such as filter and map and forEach. Because of this, it is a fairly common practice to convert arguments into an array using the following: var args = Array.prototype.slice.call(arguments); This calls the slice method from the Array prototype, passing it arguments; the slice method returns a shallow copy of arguments as a new array object. A common shorthand for this is : var args = [].slice.call(arguments); In this case, instead of calling slice from the Array prototype, it is simply being called from an empty array literal.###Optimization Unfortunately, passing arguments into any function call will cause the V8 JavaScript engine used in Chrome and Node to skip optimization on the function that does this, which can result in considerably slower performance. See this article on optimization killers. Passing arguments to any other function is known as leaking arguments. Instead, if you want an array of the arguments that lets you use you need to resort to this: var args = new Array(arguments.length); for(var i = 0; i < args.length; ++i) { args[i] = arguments[i]; } Yes it is more verbose, but in production code, it is worth it for the performance optimization. map-to-the-rescue-adding-order-to-object-properties/- en - javascript Object properties order An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method. ECMAScript Take a look in action var myObject = { z: 1, '@': 2, b: 3, 1: 4, 5: 5 }; console.log(myObject) // Object {1: 4, 5: 5, z: 1, @: 2, b: 3} for (item in myObject) {... // 1 // 5 // z // @ // b Each browser have his own rules about the order in objects bebause technically, order is unspecified. How to solve this? Map Using a new ES6 feature called Map. A Map object iterates its elements in insertion order — a for...of loop returns an array of [key, value] for each iteration. var myObject = new Map(); myObject.set('z', 1); myObject.set('@', 2); myObject.set('b', 3); for (var [key, value] of myObject) { console.log(key, value); ... // z 1 // @ 2 // b 3 Hack for old browsers Mozilla suggest: So, if you want to simulate an ordered associative array in a cross-browser environment, you are forced to either use two separate arrays (one for the keys and the other for the values), or build an array of single-property objects, etc.// Using two separate arrays var objectKeys = [z, @, b, 1, 5]; for (item in objectKeys) { myObject[item] ... // Build an array of single-property objects var myData = [{z: 1}, {'@': 2}, {b: 3}, {1: 4}, {5: 5}]; create-range-0...n-easily-using-one-line/- en - javascript Here are two compact code sequences to generate the N-element array [0, 1, ..., N-1]: Solution 1 (requires ES5) Array.apply(null, {length: N}).map(Function.call, Number); Brief explanation Array.apply(null, {length: N}) returns an N-element array filled with undefined (i.e. A = [undefined, undefined, ...]). A.map(Function.call, Number) returns an N-element array, whose index I gets the result of Function.call.call(Number, undefined, I, A) Function.call.call(Number, undefined, I, A) collapses into Number(I), which is naturally I. Result: [0, 1, ..., N-1]. For a more thorough explanation, go here. Solution 2 (requires ES6) It uses Array.from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from Array.from(new Array(N),(val,index)=>index); Solution 3 (requires ES6) Array.from(Array(N).keys()); Brief explanation A = new Array(N) returns an array with N holes (i.e. A = [,,,...], but A[x] = undefined for x in 0...N-1). F = (val,index)=>index is simply function F (val, index) { return index; } Array.from(A, F) returns an N-element array, whose index I gets the results of F(A[I], I), which is simply I. Result: [0, 1, ..., N-1]. One More Thing If you actually want the sequence [1, 2, ..., N], Solution 1 becomes: Array.apply(null, {length: N}).map(function(value, index){ return index + 1; }); and Solution 2: Array.from(new Array(N),(val,index)=>index+1); implementing-asynchronous-loops/- en - javascript Let's try out writing an asynchronous function which prints the value of the loop index every second. for (var i=0; i<5; i++) { setTimeout(function(){ console.log(i); }, 1000 * (i+1)); } The output of the above programs turns out to be> 5 > 5 > 5 > 5 > 5 So this definitely doesn't work. Reason Each timeout refers to the original i, not a copy. So the for loop increments i until it gets to 5, then the timeouts run and use the current value of i (which is 5). Well , this problem seems easy. An immediate solution that strikes is to cache the loop index in a temporary variable. for (var i=0; i<5; i++) { var temp = i; setTimeout(function(){ console.log(temp); }, 1000 * (i+1)); } But again the output of the above programs turns out to be> 4 > 4 > 4 > 4 > 4 So , that doesn't work either , because blocks don't create a scope and variables initializers are hoisted to the top of the scope. In fact, the previous block is the same as: var temp; for (var i=0; i<5; i++) { temp = i; setTimeout(function(){ console.log(temp); }, 1000 * (i+1)); } Solution There are a few different ways to copy i. The most common way is creating a closure by declaring a function and passing i as an argument. Here we do this as a self-calling function. for (var i=0; i<5; i++) { (function(num){ setTimeout(function(){ console.log(num); }, 1000 * (i+1)); })(i); } In JavaScript, arguments are passed by value to a function. So primitive types like numbers, dates, and strings are basically copied. If you change them inside the function, it does not affect the outside scope. Objects are special: if the inside function changes a property, the change is reflected in all scopes. Another approach for this would be with using let. With ES6 the let keyword is useful since it's block scoped unlike var for (let i=0; i<5; i++) { setTimeout(function(){ console.log(i); }, 1000 * (i+1)); } assignment-shorthands/- en - javascript Assigning is very common. Sometimes typing becomes time consuming for us 'Lazy programmers'. So, we can use some tricks to help us and make our code cleaner and simpler. This is the similar use of x += 23; // x = x + 23; y -= 15; // y = y - 15; z *= 10; // z = z * 10; k /= 7; // k = k / 7; p %= 3; // p = p % 3; d **= 2; // d = d ** 2; m >>= 2; // m = m >> 2; n <<= 2; // n = n << 2; n ++; // n = n + 1; n --; n = n - 1; ++ and -- operators There is a special ++ operator. It's best to explain it with an example: var a = 2; var b = a++; // Now a is 3 and b is 2 The a++ statement does this: return the value of a increment a by 1 But what if we wanted to increment the value first? It's simple: var a = 2; var b = ++a; // Now both a and b are 3 See? I put the operator before the variable. The -- operator is similar, except it decrements the value. If-else (Using ternary operator) This is what we write on regular basis. var newValue; if(value > 10) newValue = 5; else newValue = 2; We can user ternary operator to make it awesome: var newValue = (value > 10) ? 5 : 2; Null, Undefined, Empty Checks if (variable1 !== null || variable1 !== undefined || variable1 !== '') { var variable2 = variable1; } Shorthand here: var variable2 = variable1 || ''; P.S.: If variable1 is a number, then first check if it is 0. Object Array Notation Instead of using: var a = new Array(); a[0] = "myString1"; a[1] = "myString2"; Use this: var a = ["myString1", "myString2"]; Associative array Instead of using: var skillSet = new Array(); skillSet['Document language'] = 'HTML5'; skillSet['Styling language'] = 'CSS3'; Use this: var skillSet = { 'Document language' : 'HTML5', 'Styling language' : 'CSS3' }; observe-dom-changes/- en - javascript MutationObserver is a solution to listen DOM changes and do what you want to do with elements when they changed. In following example there is some emulation of dynamic content loading with help of timers, after first "target" element creation goes "subTarget". In extension code firstly rootObserver works till targetElement appearance then elementObserver starts. This cascading observing helps finally get moment when subTargetElement found. This useful to develop extensions to complex sites with dynamic content loading. const observeConfig = { attributes: true, childList: true, characterData: true, subtree: true }; function initExtension(rootElement, targetSelector, subTargetSelector) { var rootObserver = new MutationObserver(function(mutations) { console.log("Inside root observer"); targetElement = rootElement.querySelector(targetSelector); if (targetElement) { rootObserver.disconnect(); var elementObserver = new MutationObserver(function(mutations) { console.log("Inside element observer"); subTargetElement = targetElement.querySelector(subTargetSelector); if (subTargetElement) { elementObserver.disconnect(); console.log("subTargetElement found!"); } }); elementObserver.observe(targetElement, observeConfig); } }); rootObserver.observe(rootElement, observeConfig); } (function() { initExtension(document.body, "div.target", "div.subtarget"); setTimeout(function() { del = document.createElement("div"); del.innerHTML = "<div class='target'>target</div>"; document.body.appendChild(del); }, 3000); setTimeout(function() { var el = document.body.querySelector('div.target'); if (el) { del = document.createElement("div"); del.innerHTML = "<div class='subtarget'>subtarget</div>"; el.appendChild(del); } }, 5000); })(); deduplicate-an-array/- en - javascript Primitives If an Array only contains primitive values, we can deduplicate it by only using the filter and indexOf methods. var deduped = [ 1, 1, 'a', 'a' ].filter(function (el, i, arr) { return arr.indexOf(el) === i; }); console.log(deduped); // [ 1, 'a' ] ES2015 We can write this in a more compact way using an arrow function. var deduped = [ 1, 1, 'a', 'a' ].filter( (el, i, arr) => arr.indexOf(el) === i); console.log(deduped); // [ 1, 'a' ] But with the introduction of Sets and the from method, we can achieve the same result in a more concise way. var deduped = Array.from( new Set([ 1, 1, 'a', 'a' ]) ); console.log(deduped); // [ 1, 'a' ] Objects We can't use the same approach when the elements are Objects, because Objects are stored by reference and primitives are stored by value. 1 === 1 // true 'a' === 'a' // true { a: 1 } === { a: 1 } // false Therefore we need to change our approach and use a hash table. function dedup(arr) { var hashTable = {}; return arr.filter(function (el) { var key = JSON.stringify(el); var match = Boolean(hashTable[key]); return (match ? false : hashTable[key] = true); }); } var deduped = dedup([ { a: 1 }, { a: 1 }, [ 1, 2 ], [ 1, 2 ] ]); console.log(deduped); // [ {a: 1}, [1, 2] ] Because a hash table in javascript is simply an Object, the keys will always be of the type String. This means that normally we can't distinguish between strings and numbers of the same value, i.e. 1 and '1'. var hashTable = {}; hashTable[1] = true; hashTable['1'] = true; console.log(hashTable); // { '1': true } However, because we're using JSON.stringify, keys that are of the type String, will be stored as an escaped string value, giving us unique keys in our hashTable. var hashTable = {}; hashTable[JSON.stringify(1)] = true; hashTable[JSON.stringify('1')] = true; console.log(hashTable); // { '1': true, '\'1\'': true } This means duplicate elements of the same value, but of a different type, will still be deduplicated using the same implementation. var deduped = dedup([ { a: 1 }, { a: 1 }, [ 1, 2 ], [ 1, 2 ], 1, 1, '1', '1' ]); console.log(deduped); // [ {a: 1}, [1, 2], 1, '1' ] Resources Methods filter indexOf from JSON.stringify ES2015 arrow functions Sets Stack overflow remove duplicates from array flattening-multidimensional-arrays-in-javascript/- en - javascript These are the three known ways to merge multidimensional array into a single array. Given this array: var myArray = [[1, 2],[3, 4, 5], [6, 7, 8, 9]]; We wanna have this result:[1, 2, 3, 4, 5, 6, 7, 8, 9] Solution 1: Using concat() and apply() var myNewArray = [].concat.apply([], myArray); // [1, 2, 3, 4, 5, 6, 7, 8, 9] Solution 2: Using reduce() var myNewArray = myArray.reduce(function(prev, curr) { return prev.concat(curr); }); // [1, 2, 3, 4, 5, 6, 7, 8, 9] Solution 3: var myNewArray3 = []; for (var i = 0; i < myArray.length; ++i) { for (var j = 0; j < myArray[i].length; ++j) myNewArray3.push(myArray[i][j]); } console.log(myNewArray3); // [1, 2, 3, 4, 5, 6, 7, 8, 9] Solution 4: Using spread operator in ES6 var myNewArray4 = [].concat(...myArray); console.log(myNewArray4); // [1, 2, 3, 4, 5, 6, 7, 8, 9] Solution 5: Using flat() in ES10 var myNewArray5 = myArray.flat(); console.log(myNewArray5); // [1, 2, 3, 4, 5, 6, 7, 8, 9] Take a look here these 4 algorithms in action. For infinitely nested array try Lodash flattenDeep(). If you are curious about performance, here a test for check how it works. advanced-properties/- en - javascript It is possible to configure object properties in Javascript for example to set properties to be pseudo-private or readonly. This feature is available since ECMAScript 5.1, therefore supported by all recent browsers. To do so, you need to use the method defineProperty of the Object prototype like so: var a = {}; Object.defineProperty(a, 'readonly', { value: 15, writable: false }); a.readonly = 20; console.log(a.readonly); // 15 The syntax is as follows: Object.defineProperty(dest, propName, options) or for multiple definitions: Object.defineProperties(dest, { propA: optionsA, propB: optionsB, //... }) where options include the following attributes: value: if the property is not a getter (see below), value is a mandatory attribute. {a: 12} === Object.defineProperty(obj, 'a', {value: 12}) writable: set the property as readonly. Note that if the property is a nested objects, its properties are still editable. enumerable: set the property as hidden. That means that for ... of loops and stringify will not include the property in their result, but the property is still there. Note: That doesn't mean that the property is private! It can still be accessible from the outside, it just means that it won't be printed. configurable: set the property as non modifiable, e.g. protected from deletion or redefinition. Again, if the property is a nested object, its properties are still configurable. So in order to create a private constant property, you can define it like so: Object.defineProperty(obj, 'myPrivateProp', {value: val, enumerable: false, writable: false, configurable: false}); Besides configuring properties, defineProperty allows us to define dynamic properties, thanks to the second parameter being a string. For instance, let's say that I want to create properties according to some external configuration: var obj = { getTypeFromExternal(): true // illegal in ES5.1 } Object.defineProperty(obj, getTypeFromExternal(), {value: true}); // ok // For the example sake, ES6 introduced a new syntax: var obj = { [getTypeFromExternal()]: true } But that's not all! Advanced properties allows us to create getters and setters, just like other OOP languages! In that case, one cannot use the writable, enumerable and configurable properties, but instead: function Foobar () { var _foo; // true private property Object.defineProperty(obj, 'foo', { get: function () { return _foo; } set: function (value) { _foo = value } }); } var foobar = new Foobar(); foobar.foo; // 15 foobar.foo = 20; // _foo = 20 Aside for the obvious advantage of encapsulation and advanced accessors, you will notice that we didn't "call" the getter, instead we just "get" the property without parentheses! This is awesome! For instance, let's imagine that we have an object with long nested properties, like so: var obj = {a: {b: {c: [{d: 10}, {d: 20}] } } }; Now instead of doing a.b.c[0].d (where one of the properties can resolve to undefined and throw an error), we can instead create an alias: Object.defineProperty(obj, 'firstD', { get: function () { return a && a.b && a.b.c && a.b.c[0] && a.b.c[0].d } }) console.log(obj.firstD) // 10 Note If you define a getter without a setter and still try to set a value, you will get an error! This is particularly important when using helper functions such as $.extend or _.merge. Be careful! Links defineProperty Defining properties in JavaScript using-json-stringify/- en - javascript Let's say there is an object with properties "prop1", "prop2", "prop3". We can pass additional params to JSON.stringify to selectively write properties of the object to string like: var obj = { 'prop1': 'value1', 'prop2': 'value2', 'prop3': 'value3' }; var selectedProperties = ['prop1', 'prop2']; var str = JSON.stringify(obj, selectedProperties); // str // {"prop1":"value1","prop2":"value2"} The "str" will contain only info on selected properties only. Instead of array we can pass a function also. function selectedProperties(key, val) { // the first val will be the entire object, key is empty string if (!key) { return val; } if (key === 'prop1' || key === 'prop2') { return val; } return; } The last optional param it takes is to modify the way it writes the object to string. var str = JSON.stringify(obj, selectedProperties, '\t\t'); /* str output with double tabs in every line. { "prop1": "value1", "prop2": "value2" } */ array-average-and-median/- en - javascript The following examples will be based on the following array: let values = [2, 56, 3, 41, 0, 4, 100, 23]; To get the average, we have to sum up numbers and then divide by the number of values. Steps are: get the array length sum up values get the average ( sum/length) let values = [2, 56, 3, 41, 0, 4, 100, 23]; let sum = values.reduce((previous, current) => current += previous); let avg = sum / values.length; // avg = 28 Or: let values = [2, 56, 3, 41, 0, 4, 100, 23]; let count = values.length; values = values.reduce((previous, current) => current += previous); values /= count; // avg = 28 Now, to get the median steps are: sort the array get the arethmic mean of the middle values let values = [2, 56, 3, 41, 0, 4, 100, 23]; values.sort((a, b) => a - b); let lowMiddle = Math.floor((values.length - 1) / 2); let highMiddle = Math.ceil((values.length - 1) / 2); let median = (values[lowMiddle] + values[highMiddle]) / 2; // median = 13,5 With a bitwise operator: let values = [2, 56, 3, 41, 0, 4, 100, 23]; values.sort((a, b) => a - b); let median = (values[(values.length - 1) >> 1] + values[values.length >> 1]) / 2 // median = 13,5 preventing-unapply-attacks/- en - javascript By overriding the builtin prototypes, external code can cause code to break by rewriting code to expose and change bound arguments. This can be an issue that seriously breaks applications that works by using polyfill es5 methods.// example bind polyfill function bind(fn) { var prev = Array.prototype.slice.call(arguments, 1); return function bound() { var curr = Array.prototype.slice.call(arguments, 0); var args = Array.prototype.concat.apply(prev, curr); return fn.apply(null, args); }; } // unapply-attack function unapplyAttack() { var concat = Array.prototype.concat; Array.prototype.concat = function replaceAll() { Array.prototype.concat = concat; // restore the correct version var curr = Array.prototype.slice.call(arguments, 0); var result = concat.apply([], curr); return result; }; } The above function discards the prev array from the bind meaning that any .concat the first concat call following using the unapply attack will throw an error. By using Object.freeze, making an object immutable, you prevent any overriding of the builtin object prototypes.(function freezePrototypes() { if (typeof Object.freeze !== 'function') { throw new Error('Missing Object.freeze'); } Object.freeze(Object.prototype); Object.freeze(Array.prototype); Object.freeze(Function.prototype); }()); You can read more about unapply attacks here. Although this concept is called an 'unapply attack' due to some code being able to access closures that normally wouldn't be in scope, it is mostly wrong to consider this a security feature due to it not preventing an attacker with code execution from extending prototypes before the freezing happens and also still having the potential to read all scopes using various language features. ECMA modules would give realm based isolation which is much stronger than this solution however still doesn't fix the issues of third party scripts. use-destructuring-in-function-parameters/- en - javascript I am sure many of you are already familiar with the ES6 Destructuring Assignment. Did you know that you can also use it in function parameters? var sayHello = function({ name, surname }) { console.log(`Hello ${name} ${surname}! How are you?`); }; sayHello({ name: 'John', surname: 'Smith' }) // -> Hello John Smith! How are you? This is great for functions which accept an options object. For this use case, you can also add default parameters to fill in whatever values the caller leaves out, or if the caller forgets to pass one at all: var sayHello2 = function({ name = "Anony", surname = "Moose" } = {}) { console.log(`Hello ${name} ${surname}! How are you?`); }; The = {} says that the default object to be destructured for this parameter is {}, in case the caller forgets to pass the parameter, or passes one of the wrong type (more on this below). sayHello2() // -> Hello Anony Moose! How are you? sayHello2({ name: "Bull" }) // -> Hello Bull Moose! How are you? Argument Handling With plain destructuring assignment, if the the input parameter can't be matched with the function's specified object arguments, all the unmatched arguments are undefined, so you need to add code that handles this properly: var sayHelloTimes = function({ name, surname }, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); } sayHelloTimes({ name: "Pam" }, 5678) // -> Hello Pam undefined! I've seen you 5678 times before. sayHelloTimes(5678) // -> Hello undefined undefined! I've seen you undefined times before. Worse, if the parameter to be destructured is missing, an exception is thrown, probably bringing your app to a screeching halt: sayHelloTimes() // -> Uncaught TypeError: Cannot match against 'undefined' or 'null'... It's conceptually similar to accessing a property of an undefined object, just with a different exception type. Destructuring assignment with default parameters hides all the above to a certain extent: var sayHelloTimes2 = function({ name = "Anony", surname = "Moose" } = {}, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); }; sayHelloTimes2({ name: "Pam" }, 5678) // -> Hello Pam Moose! I've seen you 5678 times before. sayHelloTimes2(5678) // -> Hello Anony Moose! I've seen you undefined times before. sayHelloTimes2() // -> Hello Anony Moose! I've seen you undefined times before. As for = {}, it covers the case of a missing object, for which individual property defaults won't help at all: var sayHelloTimes2a = function({ name = "Anony", surname = "Moose" }, times) { console.log(`Hello ${name} ${surname}! I've seen you ${times} times before.`); }; sayHelloTimes2a({ name: "Pam" }, 5678) // -> Hello Pam Moose! I've seen you 5678 times before. sayHelloTimes2a(5678) // -> Hello Anony Moose! I've seen you undefined times before. sayHelloTimes2a() // -> Uncaught TypeError: Cannot match against 'undefined' or 'null'. Availability Note that destructuring assignment may not yet be available by default, in the version of Node.js or browser that you're using. For Node.js, you can try using the --harmony-destructuring flag on startup to activate this feature. know-the-passing-mechanism/- en - javascript JavaScript is pass-by-value, technically. It is neither pass-by-value nor pass-by-reference, going by the truest sense of these terms. To understand this passing mechanism, take a look at the following two example code snippets and the explanations. Example 1 var me = { // 1 'partOf' : 'A Team' }; function myTeam(me) { // 2 me = { // 3 'belongsTo' : 'A Group' }; } myTeam(me); console.log(me); // 4 : {'partOf' : 'A Team'} In above example, when the myTeam gets invoked, JavaScript is passing the reference to me object as value, as it is an object and invocation itself creates two independent references to the same object, (though the name being same here i.e. me, is misleading and gives us an impression that it is the single reference) and hence, the reference variable themselves are independent. When we assigned a new object at # 3, we are changing this reference value entirely within the myTeam function, and it will not have any impact on the original object outside this function scope, from where it was passed and the reference in the outside scope is going to retain the original object and hence the output from # 4. Example 2 var me = { // 1 'partOf' : 'A Team' }; function myGroup(me) { // 2 me.partOf = 'A Group'; // 3 } myGroup(me); console.log(me); // 4 : {'partOf' : 'A Group'} In the case of myGroup invocation, we are passing the object me. But unlike the example 1 scenario, we are not assigning this me variable to any new object, effectively meaning the object reference value within the myGroup function scope still is the original object's reference value and when we are modifying the property within this scope, it is effectively modifying the original object's property. Hence, you get the output from # 4. So does this later case not prove that javascript is pass-by-reference? No, it does not. Remember, JavaScript passes the reference as value, in case of objects. The confusion arises as we tend not to understand fully what pass by reference is. This is the exact reason, some prefer to call this as call-by-sharing. Initially posted by the author on _[ js-by-examples]( https://github.com/bmkmanoj/js-by-examples/blob/master/examples/js\ pass_by_value_or_reference.md) calculate-the-max-min-value-from-an-array/- en - javascript The built-in functions Math.max() and Math.min() find the maximum and minimum value of the arguments, respectively. Math.max(1, 2, 3, 4); // 4 Math.min(1, 2, 3, 4); // 1 These functions will not work as-is with arrays of numbers. However, there are some ways around this. Function.prototype.apply() allows you to call a function with a given this value and an array of arguments. var numbers = [1, 2, 3, 4]; Math.max.apply(null, numbers) // 4 Math.min.apply(null, numbers) // 1 Passing the numbers array as the second argument of apply() results in the function being called with all values in the array as parameters. A simpler, ES2015 way of accomplishing this is with the new spread operator. var numbers = [1, 2, 3, 4]; Math.max(...numbers) // 4 Math.min(...numbers) // 1 This operator causes the values in the array to be expanded, or "spread", into the function's arguments. detect-document-ready-in-pure-js/- en - javascript The cross-browser way to check if the document has loaded in pure JavaScript is using readyState. if (document.readyState === 'complete') { // The page is fully loaded } You can detect when the document is ready... let stateCheck = setInterval(() => { if (document.readyState === 'complete') { clearInterval(stateCheck); // document ready } }, 100); or with onreadystatechange... document.onreadystatechange = () => { if (document.readyState === 'complete') { // document ready } }; Use document.readyState === 'interactive' to detect when the DOM is ready. basics-declarations/- en - javascript Below, different ways to declare variables in JavaScript. Comments and console.log should be enough to explain what's happening here: var y, x = y = 1 //== var x; var y; x = y = 1 console.log('--> 1:', `x = ${x}, y = ${y}`) // Will print //--> 1: x = 1, y = 1 First, we just set two variables. Nothing much here.;(() => { var x = y = 2 // == var x; x = y = 2; console.log('2.0:', `x = ${x}, y = ${y}`) })() console.log('--> 2.1:', `x = ${x}, y = ${y}`) // Will print //2.0: x = 2, y = 2 //--> 2.1: x = 1, y = 2 As you can see, the code has only changed the global y, as we haven't declared the variable in the closure.;(() => { var x, y = 3 // == var x; var y = 3; console.log('3.0:', `x = ${x}, y = ${y}`) })() console.log('--> 3.1:', `x = ${x}, y = ${y}`) // Will print //3.0: x = undefined, y = 3 //--> 3.1: x = 1, y = 2 Now we declare both variables through var. Meaning they only live in the context of the closure.;(() => { var y, x = y = 4 // == var x; var y; x = y = 4 console.log('4.0:', `x = ${x}, y = ${y}`) })() console.log('--> 4.1:', `x = ${x}, y = ${y}`) // Will print //4.0: x = 4, y = 4 //--> 4.1: x = 1, y = 2 Both variables have been declared using var and only after that we've set their values. As local > global, x and y are local in the closure, meaning the global x and y are untouched. x = 5 // == x = 5 console.log('--> 5:', `x = ${x}, y = ${y}`) // Will print //--> 5: x = 5, y = 2 This last line is explicit by itself. You can test this and see the result thanks to babel. More informations available on the MDN. Special thanks to @kurtextrem for his collaboration :)! reminders-about-reduce-function-usage/- en - javascript As written in documentation the reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. Signature reduce() function accepts 2 parameters (M: mandatory, O: optional):(M) a callback reducer function to be applied that deals with a pair of previous (result of previous computation) and next element until end of the list.(O) an initial value to be used as the first argument to the first call of the callback. So let's see a common usage and later a more sophisticated one. Common usage (accumulation, concatenation) We are on Amazon website (prices in $) and our caddy is quite full, let's compute total.// my current amazon caddy purchases var items = [{price: 10}, {price: 120}, {price: 1000}]; // our reducer function var reducer = function add(sumSoFar, item) { return sumSoFar + item.price; }; // do the job var total = items.reduce(reducer, 0); console.log(total); // 1130 Optional reduce function parameter was primitive integer type 0 in that first case, but it could have been an Object, an Array...instead of a primitive type, but we will see that later. Now, cool I received a discount coupon of 20$. var total = items.reduce(reducer,-20); console.log(total); // 1110 Advanced usage (combination) This second usage example is inspired by Redux combineReducers function source. Idea behind is to separate reducer function into separate individual functions and at the end compute a new single big reducer function. To illustrate this, let's create a single object literal with some reducers function able to compute total prices in different currency $, €... var reducers = { totalInDollar: function(state, item) { // specific statements... return state.dollars += item.price; }, totalInEuros : function(state, item) { return state.euros += item.price * 0.897424392; }, totalInPounds : function(state, item) { return state.pounds += item.price * 0.692688671; }, totalInYen : function(state, item) { return state.yens += item.price * 113.852; } // more... }; Then, we create a new swiss knife function responsible for applying each partial reduce functions. that will return a new callback reducer function var combineTotalPriceReducers = function(reducers) { return function(state, item) { return Object.keys(reducers).reduce( function(nextState, key) { reducers[key](state, item); return state; }, {} ); } }; Now let's see how using it. var bigTotalPriceReducer = combineTotalPriceReducers(reducers); var initialState = {dollars: 0, euros:0, yens: 0, pounds: 0}; var totals = items.reduce(bigTotalPriceReducer, initialState); console.log(totals); /* Object {dollars: 1130, euros: 1015.11531904, yens: 127524.24, pounds: 785.81131152} */ I hope this approach can give you another idea of using reduce() function for your own needs. Your reduce function could handle an history of each computation by instance as it is done in Ramdajs with scan function JSFiddle to play with extract-unix-timestamp-easily/- en - javascript We frequently need to calculate with unix timestamp. There are several ways to grab the timestamp. For current unix timestamp easiest and fastest way is const dateTime = Date.now(); const timestamp = Math.floor(dateTime / 1000); or const dateTime = new Date().getTime(); const timestamp = Math.floor(dateTime / 1000); To get unix timestamp of a specific date pass YYYY-MM-DD or YYYY-MM-DDT00:00:00Z as parameter of Date constructor. For example const dateTime = new Date('2012-06-08').getTime(); const timestamp = Math.floor(dateTime / 1000); You can just add a + sign also when declaring a Date object like below const dateTime = +new Date(); const timestamp = Math.floor(dateTime / 1000); or for specific date const dateTime = +new Date('2012-06-08'); const timestamp = Math.floor(dateTime / 1000); Under the hood the runtime calls valueOf method of the Date object. Then the unary + operator calls toNumber() with that returned value. For detailed explanation please check the following links Date.prototype.valueOf Unary + operator toNumber() Date Javascript MDN Date.parse() helpful-console-log-hacks/- en - javascript Using conditional breakpoints to log data If you wanted to log to the console a value each time a function is called, you can use conditional break points to do this. Open up your dev tools, find the function where you'd like to log data to the console and set a breakpoint with the following condition: console.log(data.value) && false A conditional breakpoint pauses the page thread only if the condition for the breakpoint evaluates to true. So by using a condition like console.log('foo') && false it's guaranteed to evaluate to false since you're putting the literal false in the AND condition. So this will not pause the page thread when it's hit, but it will log data to the console. This can also be used to count how many times a function or callback is called. Here's how you can set a conditional breakpoint in Edge, Chrome, Firefox and Safari. Printing a function variable to console Have you ever logged a function variable to the console and weren't able to just view the function's code? The quickest way to see the function's code is to coerce it to a string using concatenation with an empty string. console.log(funcVariable + ''); DOM-event-listening-made-easy/- en - javascript Many of us are still doing these things: element.addEventListener('type', obj.method.bind(obj)) element.addEventListener('type', function (event) {}) element.addEventListener('type', (event) => {}) The above examples all create new anonymous event handlers that can't be removed when no longer needed. This may cause performance problems or unexpected logic bugs, when handlers that you no longer need still get accidentally triggered through unexpected user interactions or event bubbling.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Enviorment Setup Tutorial Basic Web Development Environment Setup Windows Subsystem for Linux (WSL) and Ubuntu Basic Web Development Environment Setup Windows Subsystem for Linux (WSL) and Ubuntu Test if you have Ubuntu installed by typing “Ubuntu” in the search box in the bottom app bar that reads “Type here to search”. If you see a search result that reads **“Ubuntu 20.04 LTS”** with “App” under it, then you have it installed. 1. In the application search box in the bottom bar, type “PowerShell” to find the application named “Windows PowerShell” 2. Right-click on “Windows PowerShell” and choose “Run as administrator” from the popup menu 3. In the blue PowerShell window, type the following: `Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux` 4. Restart your computer 5. In the application search box in the bottom bar, type “Store” to find the application named “Microsoft Store” 6. Click “Microsoft Store” 7. Click the “Search” button in the upper-right corner of the window 8. Type in “Ubuntu” 9. Click “Run Linux on Windows (Get the apps)” 10. Click the orange tile labeled **“Ubuntu”** Note that there are 3 versions in the Microsoft Store… you want the one just entitled ‘Ubuntu' 11. Click “Install” 12. After it downloads, click “Launch” 13. If you get the option, pin the application to the task bar. Otherwise, right-click on the orange Ubuntu icon in the task bar and choose “Pin to taskbar” 14. When prompted to “Enter new UNIX username”, type your first name with no spaces 15. When prompted, enter and retype a password for this UNIX user (it can be the same as your Windows password) 16. Confirm your installation by typing the command `whoami ‘as in who-am-i'`followed by Enter at the prompt (it should print your first name) 17. You need to update your packages, so type `sudo apt update` (if prompted for your password, enter it) 18. You need to upgrade your packages, so type `sudo apt upgrade` (if prompted for your password, enter it) ### Git Git comes with Ubuntu, so there's nothing to install. However, you should configure it using the following instructions. Open an Ubuntu terminal if you don't have one open already. 1. You need to configure Git, so type `git config --global user.name "Your Name"` with replacing "Your Name" with your real name. 2. You need to configure Git, so type `git config --global user.email your@email.com` with replacing " your@email.com" with your real email. **Note: if you want git to remember your login credentials type:** $ git config --global credential.helper store ### Google Chrome Test if you have Chrome installed by typing “Chrome” in the search box in the bottom app bar that reads “Type here to search”. If you see a search result that reads “Chrome” with “App” under it, then you have it installed. Otherwise, follow these instructions to install Google Chrome. 1. Open Microsoft Edge, the blue “e” in the task bar, and type in http://chrome.google.com. Click the “Download Chrome” button. Click the “Accept and Install” button after reading the terms of service. Click “Save” in the “What do you want to do with ChromeSetup.exe” dialog at the bottom of the window. When you have the option to “Run” it, do so. Answer the questions as you'd like. Set it as the default browser. 2. Right-click on the Chrome icon in the task bar and choose “Pin to taskbar”. ### Node.js Test if you have Node.js installed by opening an Ubuntu terminal and typing `node --version`. If it reports "Command 'node' not found", then you need to follow these directions. 1. In the Ubuntu terminal, type `sudo apt update` and press Enter 2. In the Ubuntu terminal, type `sudo apt install build-essential` and press Enter 3. In the Ubuntu terminal, type `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash` and press Enter 4. In the Ubuntu terminal, type `. ./.bashrc` and press Enter 5. In the Ubuntu terminal, type `nvm install --lts` and press Enter 6. Confirm that **node** is installed by typing `node --version` and seeing it print something that is not "Command not found"! ### Unzip You will often have to download a zip file and unzip it. It is easier to do this from the command line. So we need to install a linux unzip utility. In the Ubuntu terminal type: `sudo apt install unzip` and press Enter Mocha.js Test if you have Mocha.js installed by opening an Ubuntu terminal and typing `which mocha`. If it prints a path, then you're good. Otherwise, if it prints nothing, install Mocha.js by typing `npm install -g mocha`. ### Python 3 Ubuntu does not come with Python 3. Install it using the command `sudo apt install python3`. Test it by typing `python3 --version` and seeing it print a number. ### Note about WSL As of the time of writing of this document, WSL has an issue renaming or deleting files if Visual Studio Code is open. So before doing any linux commands which manipulate files, make sure you **close** Visual Studio Code before running those commands in the Ubuntu terminal. ### Some other common instillations # Installing build essentials sudo apt-get install -y build-essential libssl-dev # Nodejs and NVM curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash source ~/.profile sudo nvm install 7.10.0 sudo nvm use 7.10.0 node -v #nodemon sudo npm install -g nodemon sudo npm install -g loopback-cli # Forever to run nodejs scripts forever sudo npm install forever -g # Git - a version control system sudo apt-get update sudo apt-get install -y git xclip # Grunt - an automated task runner sudo npm install -g grunt-cli # Bower - a dependency manager sudo npm install -g bower # Yeoman - for generators sudo npm install -g yo # maven sudo apt-get install maven -y # Gulp - an automated task runner sudo npm install -g gulp-cli # Angular FullStack - My favorite MEAN boilerplate (MEAN = MongoDB, Express, Angularjs, Nodejs) sudo npm install -g generator-angular-fullstack # Vim, Curl, Python - Some random useful stuff sudo apt-get install -y vim curl python-software-properties sudo apt-get install -y python-dev, python-pip sudo apt-get install -y libkrb5-dev # Installing JDK and JRE sudo apt-get install -y default-jre sudo apt-get install -y default-jdk # Archive Extractors sudo apt-get install -y unace unrar zip unzip p7zip-full p7zip-rar sharutils rar uudeview mpack arj cabextract file-roller # FileZilla - a FTP client sudo apt-get install -y filezilla #### If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz - Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    md and html Tools For Markdown & Html Paste To Markdown Paste Excel Tabel To Markdown Paste excel to HTML
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    General Utilities General Utilities Search Photo Editor PDF Tools Github HTML Render from link Form Builder GUI Border Builder Archives Original Blog Site Text Tools Ternary Converter See the Pen Dashed Border Generator by Bryan C Guner (@bgoonz) on CodePen.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Data Structures Data Structures https://ds-unit-5-lambda.netlify.app/#. Algorithms The Algos Bgoonz Branch Python Data Structures Leetcode Algorithms
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Archive Search Resource Archive Google Drive Internet Archive Lambda Student Site Bass Station CSS Showcase Interview Speach Recognition api The Algos Bgoonz Branch Markdown Templates CURL Text Tools Ternary Converter Github HTML Render from link Form Builder GUI Border Builder Archives Original Blog Site
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Tips Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • vscode
    vscode Everything You Need to Get Started With VSCode + Extensions & Resources Commands: Everything You Need to Get Started With VSCode + Extensions & Resources Every extension or tool you could possibly need Here's a rudimentary static site I made that goes into more detail on the extensions I use… VSCodeExtensions 5fff5b9a2430bb564bfd451d--stoic-mccarthy-2c335f.netlify.app Here's the repo it was deployed from: https://github.com/bgoonz/vscode-Extension-readmes Commands: Command Palette Access all available commands based on your current context. Keyboard Shortcut: Ctrl+Shift+P### Command palette ⇧⌘P Show all commands ⌘P Show files Sidebars⌘B Toggle sidebar ⇧⌘E Explorer ⇧⌘F Search ⇧⌘D Debug ⇧⌘X Extensions ⇧^G Git (SCM) Search⌘F Find ⌥⌘F Replace ⇧⌘F Find in files ⇧⌘H Replace in files Panel⌘J Toggle panel ⇧⌘M Problems ⇧⌘U Output ⇧⌘Y Debug console ^` Terminal View⌘k z Zen mode ⌘k u Close unmodified ⌘k w Close all Debug F5 Start ⇧F5 Stop ⇧⌘F5 Restart ^F5 Start without debugging F9 Toggle breakpoint F10 Step over F11 Step into ⇧F11 Step out ⇧⌘D Debug sidebar ⇧⌘Y Debug panel Tips-N-Tricks: Here is a selection of common features for editing code. If the keyboard shortcuts aren't comfortable for you, consider installing a keymap extension for your old editor. Tip: You can see recommended keymap extensions in the Extensions view with Ctrl+K Ctrl+M which filters the search to @recommended:keymaps . Multi cursor selection To add cursors at arbitrary positions, select a position with your mouse and use Alt+Click (Option+click on macOS). To set cursors above or below the current position use: Keyboard Shortcut: Ctrl+Alt+Up or Ctrl+Alt+Down You can add additional cursors to all occurrences of the current selection with Ctrl+Shift+L. *Note: You can also change the modifier to Ctrl/Cmd for applying multiple cursors with the* `editor.multiCursorModifier` setting* . See* Multi-cursor Modifier *for details.* If you do not want to add all occurrences of the current selection, you can use Ctrl+D instead. This only selects the next occurrence after the one you selected so you can add selections one by one.### Column (box) selection You can select blocks of text by holding Shift+Alt (Shift+Option on macOS) while you drag your mouse. A separate cursor will be added to the end of each selected line. You can also use keyboard shortcuts to trigger column selection. Extensions: AutoHotkey Plus Syntax Highlighting, Snippets, Go to Definition, Signature helper and Code formatter Bash Debug A debugger extension for Bash scripts based on bashdb### Shellman Bash script snippets extension### C++ C/C++ — Preview C/C++ extension by Microsoft, read official blog post for the details Clangd — Provides C/C++ language IDE features for VS Code using clangd: code completion, compile errors and warnings, go-to-definition and cross references, include management, code formatting, simple refactorings. gnu-global-tags — Provide Intellisense for C/C++ with the help of the GNU Global tool. YouCompleteMe — Provides semantic completions for C/C++ (and TypeScript, JavaScript, Objective-C, Golang, Rust) using YouCompleteMe. C/C++ Clang Command Adapter — Completion and Diagnostic for C/C++/Objective-C using Clang command. CQuery — C/C++ language server supporting multi-million line code base, powered by libclang. Cross references, completion, diagnostics, semantic highlighting and more. More Microsoft's tutorial on using VSCode for remote C/C++ development C#, ASP . NET and . NET Core C# — C# extension by Microsoft, read official documentation for the details C# FixFormat — Fix format of usings / indents / braces / empty lines C# Extensions — Provides extensions to the IDE that will speed up your development workflow. MSBuild Project Tools VSCode Solution Explorer. NET Core Test Explorer CSS CSS Peek Peek or Jump to a CSS definition directly from HTML, just like in Brackets!- stylelint — Lint CSS/SCSS. Autoprefixer Parse CSS, SCSS, LESS and add vendor prefixes automatically.- Intellisense for CSS class names — Provides CSS class name completion for the HTML class attribute based on the CSS files in your workspace. Also supports React's className attribute.### Groovy VsCode Groovy Lint — Groovy lint, format, prettify and auto-fix### Haskell haskell-linter Haskell IDE engine — provides language server for stack and cabal projects. autocomplate-shell Java Language Support for Java(TM) by Red Hat Debugger for Java Maven for Java Lombok JavaScript Babel JavaScript Visual Studio IntelliCode — This extension provides AI-assisted development features including autocomplete and other insights based on understanding your code context. See the difference between these two here tslint — TSLint for Visual Studio Code (with "tslint.jsEnable": true ). eslint — Linter for eslint. XO — Linter for XO. AVA — Snippets for AVA. Prettier — Linter, Formatter and Pretty printer for Prettier. Schema.org Snippets — Snippets for Schema.org. Code Spell Checker — Spelling Checker for Visual Studio Code. Framework-specific: Vetur — Toolkit for Vue.js Debugger for Chrome A VS Code extension to debug your JavaScript code in the Chrome browser, or other targets that support the Chrome Debugging Protocol. Facebook Flow Flow Language Support — provides all the functionality you would expect — linting, intellisense, type tooltips and click-to-definition vscode-flow-ide — an alternative Flowtype extension for Visual Studio Code TypeScript tslint — TSLint for Visual Studio Code TypeScript Hero — Code outline view of your open TS, sort and organize your imports. Markdown markdownlint Linter for markdownlint. Markdown All in One All-in-one markdown plugin (keyboard shortcuts, table of contents, auto preview, list editing and more)### Markdown Emoji Adds emoji syntax support to VS Code's built-in Markdown preview PHP IntelliSense These extensions provide slightly different sets of features. While the first one offers better autocompletion support, the second one seems to have more features overall. PHP Intelephense PHP IntelliSense Laravel Laravel 5 Snippets — Laravel 5 snippets for Visual Studio Code Laravel Blade Snippets — Laravel blade snippets and syntax highlight support- Laravel Model Snippets — Quickly get models up and running with Laravel Model Snippets.- Laravel Artisan — Laravel Artisan commands within Visual Studio Code- DotENV — Support for dotenv file syntax Other extensions Format HTML in PHP — Formatting for the HTML in PHP files. Runs before the save action so you can still have a PHP formatter.- Composer PHP Debug — XDebug extension for Visual Studio Code PHP DocBlocker php cs fixer — PHP CS Fixer extension for VS Code, php formatter, php code beautify tool phpcs — PHP CodeSniffer for Visual Studio Code phpfmt — phpfmt for Visual Studio Code Python Python — Linting, Debugging (multi threaded, web apps), Intellisense, auto-completion, code formatting, snippets, unit testing, and more. TensorFlow TensorFlow Snippets — This extension includes a set of useful code snippets for developing TensorFlow models in Visual Studio Code. Rust Rust — Linting, auto-completion, code formatting, snippets and more Productivity ARM Template Viewer Displays a graphical preview of Azure Resource Manager (ARM) templates. The view will show all resources with the official Azure icons and also linkage between the resources.### Azure Cosmos DB Browse your database inside the vs code editor### Azure IoT Toolkit Everything you need for the Azure IoT development: Interact with Azure IoT Hub, manage devices connected to Azure IoT Hub, and develop with code snippets for Azure IoT Hub### Bookmarks Mark lines and jump to them Color Tabs An extension for big projects or monorepos that colors your tab/titlebar based on the current package### Create tests An extension to quickly generate test files.### Deploy Commands for upload or copy files of a workspace to a destination.### Duplicate Action Ability to duplicate files and directories. Error Lens Show language diagnostics inline (errors/warnings/…).### ES7 React/Redux/GraphQL/React-Native snippets Provides Javascript and React/Redux snippets in ES7### Gi Generating .gitignore files made easy### GistPad Allows you to manage GitHub Gists entirely within the editor. You can open, create, delete, fork, star and clone gists, and then seamlessly begin editing files as if they were local. It's like your very own developer library for building and referencing code snippets, commonly used config/scripts, programming-related notes/documentation, and interactive samples.### Git History View git log, file or line History Git Project Manager Automatically indexes your git projects and lets you easily toggle between them GitLink GoTo current file's online link in browser and Copy the link in clipboard.### GitLens Provides Git CodeLens information (most recent commit, # of authors), on-demand inline blame annotations, status bar blame information, file and blame history explorers, and commands to compare changes with the working tree or previous versions.### Git Indicators Atom-like git indicators on active panel### GitHub Provides GitHub workflow support. For example browse project, issues, file (the current line), create and manage pull request. Support for other providers (e.g. gitlab or bitbucket) is planned. Have a look at the README.md on how to get started with the setup for this extension. GitHub Pull Request Monitor This extension uses the GitHub api to monitor the state of your pull requests and let you know when it's time to merge or if someone requested changes.### GitLab Workflow Adds a GitLab sidebar icon to view issues, merge requests and other GitLab resources. You can also view the results of your GitLab CI/CD pipeline and check the syntax of your _.gitlab-ci.yml._ Gradle Tasks Run gradle tasks in VS Code.### Icon Fonts Snippets for popular icon fonts such as Font Awesome, Ionicons, Glyphicons, Octicons, Material Design Icons and many more! Import Cost This extension will display inline in the editor the size of the imported package. The extension utilizes webpack with babili-webpack-plugin in order to detect the imported size. Jira and Bitbucket Bringing the power of Jira and Bitbucket to VS Code — With Atlassian for VS Code you can create and view issues, start work on issues, create pull requests, do code reviews, start builds, get build statuses and more!### JS Parameter Annotations Provides annotations on function calls in JS/TS files to provide parameter names to arguments.### Jumpy Provides fast cursor movement, inspired by Atom's package of the same name.### Kanban*Simple Kanban board for use in Visual Studio Code, with time tracking and Markdown support.* Live Server Launch a development local Server with live reload feature for static & dynamic pages.### Multiple clipboards Override the regular Copy and Cut commands to keep selections in a clipboard ring ngrok for VSCode ngrok allows you to expose a web server running on your local machine to the internet. Just tell ngrok what port your web server is listening on. This extension allows you to control ngrok from the VSCode command palette### Instant Markdown Simply, edit markdown documents in vscode and instantly preview it in your browser as you type.### npm Intellisense Visual Studio Code plugin that autocompletes npm modules in import statements.### Parameter Hints Provides parameter hints on function calls in JS/TS/PHP files.### Partial Diff Compare (diff) text selections within a file, across different files, or to the clipboard### Paste JSON as Code Infer the structure of JSON and paste is as types in many programming languages### Path IntelliSense Visual Studio Code plugin that autocompletes filenames### Power Tools Extends Visual Studio Code via things like Node.js based scripts or shell commands, without writing separate extensions### PrintCode PrintCode converts the code being edited into an HTML file, displays it by browser and prints it.### Project Manager Easily switch between projects. Project Dashboard VSCode Project Dashboard is a Visual Studio Code extension that lets you organize your projects in a speed-dial like manner. Pin your frequently visited folders, files, and SSH remotes onto a dashboard to access them quickly.### Rainbow CSV Highlight columns in comma, tab, semicolon and pipe separated files, consistency check and linting with CSVLint, multi-cursor column editing, column trimming and realignment, and SQL-style querying with RBQL.### Remote Development Allows users to open any folder in a container, on a remote machine, container or in Windows Subsystem for Linux(WSL) and take advantage of VS Code's full feature set.### Remote VSCode Allow user to edit files from Remote server in Visual Studio Code directly. REST Client Allows you to send HTTP request and view the response in Visual Studio Code directly.### Settings Sync Synchronize settings, snippets, themes, file icons, launch, key bindings, workspaces and extensions across multiple machines using GitHub Gist### Text Power Tools All-in-one extension for text manipulation: filtering (grep), remove lines, insert number sequences and GUIDs, format content as table, change case, converting numbers and more. Great for finding information in logs and manipulating text.### Todo Tree Custom keywords, highlighting, and colors for TODO comments. As well as a sidebar to view all your current tags.### Toggle Quotes Cycle between single, double and backtick quotes### Typescript Destructure TypeScript Language Service Plugin providing a set of source actions for easy objects destructuring### WakaTime Automatic time tracker and productivity dashboard showing how long you coded in each project, file, branch, and language. Formatting & Beautification Better Align Align your code by colon(:), assignment(=, +=, -=, *=, /=) and arrow(=> ). It has additional support for comma-first coding style and trailing comment. And it doesn't require you to select what to be aligned, the extension will figure it out by itself.### Auto Close Tag Automatically add HTML/XML close tag, same as Visual Studio IDE or Sublime Text### Auto Rename Tag Auto rename paired HTML/XML tags### beautify Beautify code in place for VS Code html2pug Transform html to pug inside your Visual Studio Code, forget about using an external page anymore. ECMAScript Quotes Transformer Transform quotes of ECMAScript string literals### Paste and Indent Paste code with “correct” indentation Sort Lines Sorts lines of text in specific order### Surround A simple yet powerful extension to add wrapper templates around your code blocks.### Wrap Selection Wraps selection or multiple selections with symbol or multiple symbols Formatting Toggle Allows you to toggle your formatter on and off with a simple click Bracket Pair Colorizer This extension allows matching brackets to be identified with colours. The user can define which characters to match, and which colours to use.### Auto Import Automatically finds, parses and provides code actions and code completion for all available imports. Works with Typescript and TSX. shell-format shell script & Dockerfile & dotenv format### Vscode Google Translate Quickly translate selected text right in your code### Explorer Icons Material Icon Theme### Uncategorized Browser Preview Browser Preview for VS Code enables you to open a real browser preview inside your editor that you can debug. Browser Preview is powered by Chrome Headless, and works by starting a headless Chrome instance in a new process. This enables a secure way to render web content inside VS Code, and enables interesting features such as in-editor debugging and more! FYI:… I HAVE TRIED ENDLESSLEY TO GET THE DEBUGGER TO WORK IN VSCODE BUT IT DOES NOT… I SUSPECT THAT'S WHY IT HAS A 3 STAR RATING FOR AN OTHERWISE PHENOMINAL EXTENSION.### CodeRoad Play interactive tutorials in your favorite editor.### Code Runner Run code snippet or code file for multiple languages: C, C++, Java, JavaScript, PHP, Python, Perl, Ruby, Go, Lua, Groovy, PowerShell, BAT/CMD, BASH/SH, F# Script, C# Script, VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml Script### Code Time Automatic time reports by project and other programming metrics right in VS Code.### Color Highlight Highlight web colors in your editor### Output Colorizer Syntax highlighting for the VS Code Output Panel and log files### Dash Dash integration in Visual Studio Code### Edit with Shell Command Leverage your favourite shell commands to edit text### Editor Config for VS Code Editor Config for VS Code ftp-sync Auto-sync your work to remote FTP server### Highlight JSX/HTML tags Highlights matching tags in the file. Indent Rainbow A simple extension to make indentation more readable.### Password Generator Create a secure password using our generator tool. Help prevent a security threat by getting a strong password today.### PlatformIO An open source ecosystem for IoT development: supports 350+ embedded boards, 20+ development platforms, 10+ frameworks. Arduino and ARM mbed compatible.### Polacode Polaroid for your code 📸. Note: Polacode no longer works as of the most recent update… go for Polacode2020 or CodeSnap…### Quokka This one is super cool! Rapid prototyping playground for JavaScript and TypeScript in VS Code, with access to your project's files, inline reporting, code coverage and rich output formatting.### Slack Send messages and code snippets, upload files to Slack Personally I found this extension to slow down my editor in addition to confliction with other extensions: (I have over 200 as of this writing)….. yes I have been made fully aware that I have a problem and need to get help### Spotify No real advantage over just using Spotify normally… it's problematic enough in implementation that you won't save any time using it. Further, it's a bit tricky to configure … or at least it was the last time I tried syncing it with my spotify account. Provides integration with Spotify Desktop client. Shows the currently playing song in status bar, search lyrics and provides commands for controlling Spotify with buttons and hotkeys.### SVG A Powerful SVG Language Support Extension(beta). Almost all the features you need to handle SVG.### SVG Viewer View an SVG in the editor and export it as data URI scheme or PNG. Text Marker (Highlighter) Highlight multiple text patterns with different colors at the same time. Highlighting a single text pattern can be done with the editor's search functionality, but it cannot highlight multiple patterns at the same time, and this is where this extension comes handy.### ESDOC MDN THIS IS A MUST HAVE Quickly bring up helpful MDN documentation in the editor### Themes: In the interest of not making the reader scroll endlessly as I often do… I've made a separate post for that here. If you've made it this far, I thank you! My Favorite VSCode Themes Themesbryanguner.medium.com If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz's gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: Web-Dev-Resource-Hub Edit description web-dev-resource-hub.netlify.app By Bryan Guner on March 18, 2021. Canonical link Exported from Medium on May 23, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Developer Resources Web Dev Resources Photo by Roman Synkevych on Unsplash### Web Development Check cross-browser compatibility for CSS, JavaScript and HTML Modern front-end Cheatsheets Check out what your favorite company's stack is A Guide to Becoming a Full-Stack Developer in 2017 What happens when you type a URL into a web browser JavaScript Airbnb JavaScript Style Guide Regular Expressions Demystified ECMAScript compatibility table GIT HubSpot's Intro to Git/GitHub including Pull Requests & Merging Express Express Starter Node.js Fetch vs. Axios.js for making http requests ## Sequelize Sequelize: Getting Started[Sequelize reference by @tmkelly28]( https://github.com/tmkelly28/sequelize-reference) Short but useful Sequelize querying cheatsheet Study Guides Express & Sequelize Boilerplate/Study Guide React React Casts — Series of React tutorials by Cassio React Dev Tool Google Chrome Extension create-react-app: Create React apps with no build configuration. Find the perfect React starter template Formik — Build forms in React, without the tears 😭 Redux Getting Started with Redux (free course by Dan Abramov) Building React Applications with Idiomatic Redux (free course by Dan Abramov) Redux Dev Tool Chrome Extension Redux Middleware redux-freeze: avoid accidental in-place mutations of state redux-saga: manage redux side-effects with es6 generators redux-promise-middleware: A thunk alternative with more bells and whistles ## CSS Specificity Calculator Tool for making clip-paths quickly with CSS Command Line Useful commands Get your IP address in Mac OSX/Unix: ifconfig | grep 'inet ' Atom Atom command cheat sheet VS Code Keystroke cheat sheet Daniel's Config Sublime Keystroke cheat sheet Configuring Sublime Text 3 for Modern ES6 JS Projects Whiteboard Interviews algoexpert.io (Made by FSA alumni) JavaScript implementation of popular algorithms and data structures Code Wars Geeks for Geeks Interview Cake Leet Code Coder Byte Hacker Rank Cracking the Coding Interview Here's a repo where I hoard resource lists! bgoonz/Cumulative-Resource-List Inspired by Awesome Lists. Contribute to bgoonz/Cumulative-Resource-List development by creating an account on GitHub. github.com MOAR!- Ansible - Awesome Lists - CI/CD - Data Science - Docker - DynamoDB - Elasticsearch - Environment Setups - Epic Github Repos - Golang - Grafana - Great Blogs - Knowledge Base - Kubernetes - Kubernetes Storage - Machine Learning - Monitoring - MongoDB - Programming - Queues - Self Hosting - Email Server Setups - Mailscanner Server Setups - Serverless - Sysadmin References - VPN - Web Frameworks Ansible Kubernetes on LXC with Ansible Awesome Lists Awesome ChatOps Awesome Scalability Awesome Drone Epic Github Repos mlabouardy Authentication Nginx ES and Kibana Proxy with LDAP Data Science bulutyazilim — datascience awesome list Grafana Grafana Dashboards @mlabouardy Docker Deploy Stacks to your Swarm: 🐳 ❤️ Logging: shazChaudhry Swarm GELF Stack Metrics: StefanProdan — Prometheus, Grafana, cAdvisor, Node Exporter and Alert Manager Mlabouardy — Telegraf, InfluxDB, Chronograf, Kapacitor & Slack Awesome Docker Repos Jess's Dockerfiles Firecat53's Dockerfiles RaspberryPi ARM Images: arm32v6/alpine:edge arm32v6/golang:alpine arm32v6/haproxy:alpine arm32v6/node:alpine arm32v6/openjdk:alpine arm32v6/postgres:alpine arm32v6/python:2.7-alpine3.6 arm32v6/python:3.6-alpine3.6 arm32v6/rabbitmq:alpine arm32v6/redis:alpine arm32v6/ruby:alpine3.6 arm32v6/tomcat:alpine arm32v6/traefik:latest arm32v7/debian:lates hypriot/rpi-redis jixer/rpi-mongo alexellis/armhf zeiot: rpi-prometheus stack larmog Rpi MongoDB ARM Swarm Docker Image Repositories Docker Hub: arm32v6 Docker Hub: armv7 Github: Luvres Armhf Apache/PHP7 on Alpine Tomcat on Alpine Nginx (jwilder) Alpine Images (smebberson) SameerSbn Linuxserver.io Apache-PHP5 Apache-PHP-Email Docker-Awesome-Lists Java Docker Services shouse Docker Awesome List Docker Blogs: Whoami used in Traefik Docs Sqlite with Docker Rails with Postgres and Redis Async Tasks with Flask and Redis Flask and Postgres Elastic Beats on RaspberryPi Docker Storage Rancher Convoy Flocker EMC ScaleIO RexRay Ceph with Ansible ContainX OpenFaas: FaaS Releases FaaS Workshop Prometheus / Grafana on Swarm: StefanProdan — SwarmProm Monitoring with Prometheus UschtWill — Prometheus Grafana Elastalert Chmod-Org Promethus with Blackbox Finestructure: Prometheus Tutorial Logging / Kibana / Beats Libraries Loguru | Flask Example with Loguru Frameworks shazChaudhry Swarm GELF Stack Continious Integration: Circle-CI PHP with Circle-CI Concourse Setup Concourse Environment with Docker Getting Started with Concourse and Docker Concourse Gated Pipelines Concourse Boilerplate Jenkins Modess — PHP with Jenkins CI/CD Nodejs Tutorial with Jenkins CI/CD Nodejs Tutorial with Jenkins @medium Epic CICD workflow with Jenkins, Gitlab, Sonar, Nexus SwarmCi SwarmCI Travis-CI Getting Started with Travis-CI (Original Docs) Getting Started with Travis-CI (dwyl — nodejs) Blog Site with Travis-CI (Python) Build Tests with Python on Travis-CI Moving app with Travis-CI LambCI LambCI DynamoDB DynamoDB Docs AWS DynamoDB: SQL to NoSQL DynamoDB Best Practices Choosing the Right Partition Key 10 Things you should know DynamoDB General Info Understanding DynamoDB Elasticsearch Elasticsearch Documentation General Recommendation How Many Shards in my Cluster Managing Time-Based Indices Efficiently Elasticsearch Best Practices (Bonsai.io) AWS ES — Scaling up my Domain Elasticsearch Cheetsheets: My ES Cheatsheet Elasticsearch Blogs Maximize Elasticsearch Indexing Performance Autoritative Guide to ES Performance Tuning Full text Search Queries Query Elasticsearch Elasticsearch Tools Export Data from ES to ES Environment Setups: Golang Knowledge Base KB HTTPS How does HTTPS work (Miguel Grinberg) Kubernetes Awesome Kubernetes Kubernetes Cheatsheet Getting Started: Python application on Kubernetes Kubernetes Deployments: The Ultimate Guide Prometheus Monitoring Stack with Kubernetes on DO Traefik as an Ingress Controller on Minikube Traefik Ingress with Kubernetes Manual Connect your Kubernetes from Outside HTTPS Letsencrypt on k3s Kubernetes: Nodeport vs Loadbalancer Prometheus Monitoring Pipeline on Kubernetes Building a Kubernetes CI/CD Pipeline with Rancher Building a Kubernetes CI/CD Pipeline with AWS Gitea and Drone CI/CD on k3s Serverless with Kubernetes using OpenFaaS and Linkerd2 Managing Kubernetes with kubectl OpenFaas Workshop on k3s Kubernetes Hands-On Lab with collabnix Create ReadWrite Persistent Volumes on Kubernetes Kubernetes Clusters with k3s and multipass Kubernetes Storage Kadalu Rancher: Longhorn Storage Golang Generate Fake Random Data with Golang Ultimate Golang Study Guide Great Blogs Exratione.com Joelabrahamsson.com Benjamin Cane Michael Herman Charles Leifer Labouardy Mark's Tech Blog Linuxkit: Getting Started with Linuxkit Logging Stacks shazChaudhry Swarm GELF Stack Machine Learning: PracticalAI Metrics: AppMetrics with Flask Scales: Metrics for Python Graphite: Python Flask Metrics MongoDB: Setup MongoDB Cluster MongoDB Scripts MongoDB Monitoring Tools Roles with MongoDB Queries: Guru99 Queries: Exploratory Queries: Tutorialspoint Queries: MongoDB Cheatsheet Monitoring Docker Swarm Monitoring Stack: Telegraf, InfluxDB, Chronograf, Kapacitor github source Docker Swarm Monitoring Stack: Prometheus, Grafana, cAdvisor, Node Exporter github source Prometheus Grafana Docker Prometheus Blog Seros Memcached Monitoring Nagios with Nagios Graph Slack Alerts with Prometheus Local Prometheus Stack Docker Swarm Promethus Setup #1 Docker Swarm Prometheus Setup #1: Blog Docker Swarm Promethus Setup #2 Docker Swarm Promethus Setup #3 (Blackbox) Uptime (fzaninotto) Monitoring and Alerting Cabot (Lightweight Pagerduty) Nagios Monitoring as Statuspages Statuspage (darkpixel Cachet Programming Golang: Golang Tutorials Golang Wiki Java: Java Spring Boot Examples Python Ruby: Learn Ruby: Learn Ruby the Hard Way Learn Ruby: Ruby for Beginners Learn Ruby: Launch School Learn Ruby: Arrays Install Ruby Environment on Mac Ruby on Rails: Tutorial: Ruby On Rails Tutorial: ROR on Docker Queues Alpine SQS Kombu: Messaging library for Python Python Job Queues with Redis Sysadmin References: Sysadmin Command References Linux Performance Observability Tools Troubleshooting High IO Wait IO Monitoring in Linux IOStat and VMStat for Performance Monitoring Debugging Heavy Load Self Hosting Email Server Setups Extratione: Postfix Dovecot MySQL Virtual Users Postfixadmin Extratione: Postfix Dovecot MySQL Virtual Users Postfixadmin (Ubuntu 18) Linuxsize: Postfix Dovecot MySQL Virtual Users Postfixadmin Howtoforge: Postfix, MySQL, Dovecto, Dspam Linuxsize: VirtualUsers, MySQL, Postfix, Dovecot Mailscanner Server Setups Spamassassin with Debian 8 Financial SelfHosted Firefly Self Hosting Frameworks: Sandstorm Serverless Serverless Zappa Serverless Contact Form Serverless Authentication on AWS (danilop) VPN: VPN-Howto: Ubuntu OpenVPN Script Ubuntu IPSec Script DO — Setup OpenVPN on Ubuntu Elasticshosts — IPSec VPN PPTP/IPSec/OpenVPN Auto Install Website Templates Resume Templates johnmarcampbell resume-site Web Frameworks Python Flask: Python Flask Upload Example Awesome Flask — humiaozuzu Awesome Flask Apps — Greyli Flask over HTTPS (MG) Flask Advanced Patterns Flask MVC Boilerplate If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz's gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Ada Introduction to Ada Android Android Tutorial - tutlane Javatpoint Android Tutorial Bash Help messages will explain everything Learn Shell Programming C Learn C C Sharp C# Tutorial - tutlane C# Tutorial - W3Schools Codeasy Learn C# Learn C# - Codecademy C++ C++ Tutorial - W3Schools CppKoans Clojure 4Clojure - Koans Clojure Koans ClojureScript Koans Try Clojure Cloud Computing AWS API Gateway - registration required AWS Identity and Access Management (IAM) - registration required AWS Lambda - registration required AWS Simple Storage Service (S3) - registration required Google Cloud Platform CoffeeScript Coffeescript Style Guide Smooth CoffeeScript, Interactive Edition Dart Dart Official Codelabs Erlang Try Erlang Git git-game git-game-v2 Githug (Tutorial in shell) Learn Git Branching Learn Git with Bitbucket Cloud Try Git GLSL The Book of Shaders Go Go Koans Start using Go - Microsoft The Go Tutorial Haskell Try Haskell! HTML / CSS CSS Diner CSS Tutorial - W3Schools Flex Box Adventure - Nick Bull Flexbox Defense Flexbox Froggy FreeCodeCamp: Responsive Web Design Course Grid Attack - Nick Bull Grid Garden HTML Tutorial - W3Schools Knights of the Flexbox Table Learn by doing beginner projects Learn HTML & CSS interactively Prototyping a professional website Bootstrap Bootstrap Tutorial - tutlane Front End Libraries: Bootstrap Java CodingBat code practice Java at Codecademy Java Tutorial - W3Schools Learn Java Learneroo Java tutorial JavaScript ABC of JavaScript : An Interactive JavaScript Tutorial Codecademy jquery track ES6 Interactive Guide Functional Programming in Javascript JavaScript Algorithms and Data Structures Certification Javascript interactive tutorial on CodeCademy JavaScript interactive tutorial on CoderMania JavaScript Tutorial - W3Schools Javascripting Learn JavaScript Learn knockout.js Learn to Code for Free – Grasshopper Learning Advanced JavaScript Try jQuery Angular.js Angular Basics Angular Tutorial - W3Schools AngularJS - Step by Logical Step AngularJS Tutorial - tutlane egghead.io: Learn AngularJS with Tutorial Videos & Training Learn AngularJS with free interactive lessons jQuery Front End Libraries: jQuery React Front End Libraries: React React Tutorial Kotlin Kotlin tutorial Language Agnostic CodeCombat - Python, JavaScript, CoffeeScript, Clojure, Lua, Io Codility Introduction to the Coding Interview Prep Algorithms (freeCodeCamp) Python Tutor - Python, Java, JavaScript, TypeScript, Ruby, C, C++ The Fullstack Tutorial for GraphQL Operating systems Learning operating system development using Linux kernel and Raspberry Pi - Sergey Matyukevich (:construction: in process) LaTeX Learn LaTeX in 30 minutes Lisp Lisp Koans MATLAB Interactive Tutorials for MATLAB, Simulink, Signal Processing, Controls, and Computational Mathematics Node Node School Node.js Tutorial - tutlane Node.js Tutorial - W3Schools NoSQL MongoDB Koans Try Redis Objective-C Try Objective-C Ocaml Try Ocaml PHP CodeCademy PHP Learn PHP PHP tutorial - W3Schools PostgreSQL PostgreSQL Tutorial Python Codecademy Python course How to Think Like a Computer Scientist: Learning with Python, Interactive Edition Learn Python Learn Python Step by Step Python for Everybody - Interactive - Barbara Ericson Python Koans Python Pandas Tutorial: A Complete Introduction for Beginners - George McIntire, Brendan Martin, Lauren Washington Python Programming Language - GeeksforGeeks Python Tutorial - tutlane Python Tutorial - W3Schools Ruby CodeCademy Ruby Ruby Koans The Odin Project Try Ruby Rust Rustlings Scala A Tour of Scala - an interactive scala tutorial Scala Exercises Selenium Selenium Tutorial - Web Automation SQL Intro to SQL: Querying and managing data - Khan Academy SQL at Codecademy SQL Server Tutorial - tutlane SQL Tutorial - W3Schools SQLBolt Vim Interactive Vim Tutorial
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Postgresql Cheat Sheet Postgresql Cheat Sheet PostgreSQL commands CODEX PostgreSQL Cheat Sheet Each table is made up of rows and columns. If you think of a table as a grid, the column go from left to right across the grid and each entry of data is listed down as a row. ALLOFMYOTHERARTICLES bryanguner.medium.com Each row in a relational is uniquely identified by a primary key. This can be by one or more sets of column values. In most scenarios it is a single column, such as employeeID. Every relational table has one primary key. Its purpose is to uniquely identify each row in the database. No two rows can have the same primary key value. The practical result of this is that you can select every single row by just knowing its primary key. SQL Server UNIQUE constraints allow you to ensure that the data stored in a column, or a group of columns, is unique among the rows in a table. Although both UNIQUE and PRIMARY KEY constraints enforce the uniqueness of data, you should use the UNIQUE constraint instead of PRIMARY KEY constraint when you want to enforce the uniqueness of a column, or a group of columns, that are not the primary key columns. Different from PRIMARY KEY constraints, UNIQUE constraints allow NULL. Moreover, UNIQUE constraints treat the NULL as a regular value, therefore, it only allows one NULL per column. Create a new role: CREATE ROLE role_name; Create a new role with a username and password: CREATE ROLE username NOINHERIT LOGIN PASSWORD password; Change role for the current session to the new_role: SET ROLE new_role; Allow role_1 to set its role as role_2: GRANT role_2 TO role_1; Managing databases Create a new database: CREATE DATABASE [IF NOT EXISTS] db_name; Delete a database permanently: DROP DATABASE [IF EXISTS] db_name; Managing tables Create a new table or a temporary table CREATE [TEMP] TABLE [IF NOT EXISTS] table_name( pk SERIAL PRIMARY KEY, c1 type(size) NOT NULL, c2 type(size) NULL, ... ); Add a new column to a table: ALTER TABLE table_name ADD COLUMN new_column_name TYPE; Drop a column in a table: ALTER TABLE table_name DROP COLUMN column_name; Rename a column: ALTER TABLE table_name RENAME column_name TO new_column_name; Set or remove a default value for a column: ALTER TABLE table_name ALTER COLUMN [SET DEFAULT value | DROP DEFAULT] Add a primary key to a table. ALTER TABLE table_name ADD PRIMARY KEY (column,...); Remove the primary key from a table. ALTER TABLE table_name DROP CONSTRAINT primary_key_constraint_name; Rename a table. ALTER TABLE table_name RENAME TO new_table_name; Drop a table and its dependent objects: DROP TABLE [IF EXISTS] table_name CASCADE; Managing views Create a view: CREATE OR REPLACE view_name AS query; Create a recursive view: CREATE RECURSIVE VIEW view_name(column_list) AS SELECT column_list; Create a materialized view: CREATE MATERIALIZED VIEW view_name AS query WITH [NO] DATA; Refresh a materialized view: REFRESH MATERIALIZED VIEW CONCURRENTLY view_name; Drop a view: DROP VIEW [ IF EXISTS ] view_name; Drop a materialized view: DROP MATERIALIZED VIEW view_name; Rename a view: ALTER VIEW view_name RENAME TO new_name; Managing indexes Creating an index with the specified name on a table CREATE [UNIQUE] INDEX index_name ON table (column,...) Removing a specified index from a table DROP INDEX index_name; Querying data from tables Query all data from a table: SELECT * FROM table_name; Query data from specified columns of all rows in a table: SELECT column_list FROM table; Query data and select only unique rows: SELECT DISTINCT (column) FROM table; Query data from a table with a filter: SELECT * FROM table WHERE condition; Assign an alias to a column in the result set: SELECT column_1 AS new_column_1, ... FROM table; Query data using the LIKE operator: SELECT * FROM table_name WHERE column LIKE '%value%' Query data using the BETWEEN operator: SELECT * FROM table_name WHERE column BETWEEN low AND high; Query data using the IN operator: SELECT * FROM table_name WHERE column IN (value1, value2,...); Constrain the returned rows with the LIMIT clause: SELECT * FROM table_name LIMIT limit OFFSET offset ORDER BY column_name; Query data from multiple using the inner join, left join, full outer join, cross join and natural join: SELECT * FROM table1 INNER JOIN table2 ON conditions SELECT * FROM table1 LEFT JOIN table2 ON conditions SELECT * FROM table1 FULL OUTER JOIN table2 ON conditions SELECT * FROM table1 CROSS JOIN table2; SELECT * FROM table1 NATURAL JOIN table2; Return the number of rows of a table. SELECT COUNT (*) FROM table_name; Sort rows in ascending or descending order: SELECT select_list FROM table ORDER BY column ASC [DESC], column2 ASC [DESC],...; Group rows using GROUP BY clause. SELECT * FROM table GROUP BY column_1, column_2, ...; Filter groups using the HAVING clause. SELECT * FROM table GROUP BY column_1 HAVING condition; Set operations Combine the result set of two or more queries with UNION operator: SELECT * FROM table1 UNION SELECT * FROM table2; Minus a result set using EXCEPT operator: SELECT * FROM table1 EXCEPT SELECT * FROM table2; Get intersection of the result sets of two queries: SELECT * FROM table1 INTERSECT SELECT * FROM table2; Modifying data Insert a new row into a table: INSERT INTO table(column1,column2,...) VALUES(value_1,value_2,...); Insert multiple rows into a table: INSERT INTO table_name(column1,column2,...) VALUES(value_1,value_2,...), (value_1,value_2,...), (value_1,value_2,...)... Update data for all rows: UPDATE table_name SET column_1 = value_1, ...; Update data for a set of rows specified by a condition in the WHERE clause. UPDATE table SET column_1 = value_1, ... WHERE condition; Delete all rows of a table: DELETE FROM table_name; Delete specific rows based on a condition: DELETE FROM table_name WHERE condition; Performance Show the query plan for a query: EXPLAIN query; Show and execute the query plan for a query: EXPLAIN ANALYZE query; Collect statistics: ANALYZE table_name; Postgres & JSON: Creating the DB and the Table DROP DATABASE IF EXISTS books_db; CREATE DATABASE books_db WITH ENCODING='UTF8' TEMPLATE template0; DROP TABLE IF EXISTS books; CREATE TABLE books ( id SERIAL PRIMARY KEY, client VARCHAR NOT NULL, data JSONb NOT NULL ); Populating the DB INSERT INTO books(client, data) values( 'Joe', '{ "title": "Siddhartha", "author": { "first_name": "Herman", "last_name": "Hesse" } }' ); INSERT INTO books(client, data) values('Jenny', '{ "title": "Bryan Guner", "author": { "first_name": "Jack", "last_name": "Kerouac" } }'); INSERT INTO books(client, data) values('Jenny', '{ "title": "100 años de soledad", "author": { "first_name": "Gabo", "last_name": "Marquéz" } }'); Lets see everything inside the table books: SELECT * FROM books; Output:### `->` operator returns values out of JSON columns Selecting 1 column: SELECT client, data->'title' AS title FROM books; Output: Selecting 2 columns: SELECT client, data->'title' AS title, data->'author' AS author FROM books; Output:### `->` vs `->>` The -> operator returns the original JSON type (which might be an object), whereas ->> returns text. Return NESTED objects You can use the -> to return a nested object and thus chain the operators: SELECT client, data->'author'->'last_name' AS author FROM books; Output:### Filtering Select rows based on a value inside your JSON: SELECT client, data->'title' AS title FROM books WHERE data->'title' = '"Bryan Guner"'; Notice WHERE uses -> so we must compare to JSON '"Bryan Guner"' Or we could use ->> and compare to 'Bryan Guner' Output:### Nested filtering Find rows based on the value of a nested JSON object: SELECT client, data->'title' AS title FROM books WHERE data->'author'->>'last_name' = 'Kerouac'; Output:### A real world example CREATE TABLE events ( name varchar(200), visitor_id varchar(200), properties json, browser json ); We're going to store events in this table, like pageviews. Each event has properties, which could be anything (e.g. current page) and also sends information about the browser (like OS, screen resolution, etc). Both of these are completely free form and could change over time (as we think of extra stuff to track). INSERT INTO events VALUES ( 'pageview', '1', '{ "page": "/" }', '{ "name": "Chrome", "os": "Mac", "resolution": { "x": 1440, "y": 900 } }' ); INSERT INTO events VALUES ( 'pageview', '2', '{ "page": "/" }', '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1920, "y": 1200 } }' ); INSERT INTO events VALUES ( 'pageview', '1', '{ "page": "/account" }', '{ "name": "Chrome", "os": "Mac", "resolution": { "x": 1440, "y": 900 } }' ); INSERT INTO events VALUES ( 'purchase', '5', '{ "amount": 10 }', '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1024, "y": 768 } }' ); INSERT INTO events VALUES ( 'purchase', '15', '{ "amount": 200 }', '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1280, "y": 800 } }' ); INSERT INTO events VALUES ( 'purchase', '15', '{ "amount": 500 }', '{ "name": "Firefox", "os": "Windows", "resolution": { "x": 1280, "y": 800 } }' ); Now lets select everything: SELECT * FROM events; Output:### JSON operators + PostgreSQL aggregate functions Using the JSON operators, combined with traditional PostgreSQL aggregate functions, we can pull out whatever we want. You have the full might of an RDBMS at your disposal. Lets see browser usage: SELECT browser->>'name' AS browser, count(browser) FROM events GROUP BY browser->>'name'; Output:- Total revenue per visitor: SELECT visitor_id, SUM(CAST(properties->>'amount' AS integer)) AS total FROM events WHERE CAST(properties->>'amount' AS integer) > 0 GROUP BY visitor_id; Output:- Average screen resolution - `SELECT AVG(CAST(browser->'resolution'->>'x' AS integer)) AS width, AVG(CAST(browser->'resolution'->>'y' AS integer)) AS height FROM events;` Output:#### If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: a/A-Student-Resources Edit description goofy-euclid-1cd736.netlify.app If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz's gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site:
    https://bgoonz-blog.netlify.app/images/code.png
  • Gatsby Plugins For This Sites Content Model
    Notes Template Title Description:/_ Description here _/ ToC: Title ToC: Main Notes: Resource Links: 10 X 10 Table Headers H1 H2 H3 H4 H5 H6 Alt-H1 Alt-H2 Emphasis Lists Links Images Code and Syntax Highlighting Tables Blockquotes Inline HTML Horizontal Rule Line Breaks YouTube Videos This is an H1 This is an H2 This is an H3 This is an H4 Quoting Unordered Lists Ordered Lists Video Embeds Code Blocks Tables Main Notes: Resource Links: 10 X 10 Table Headers# H1 ## H2 ### H3 #### H4 ##### H5 ###### H6 Alternatively, for H1 and H2, an underline-ish style: Alt-H1 ====== Alt-H2 ------ H1 H2 H3 H4 H5 H6 Alternatively, for H1 and H2, an underline-ish style: Alt-H1 Alt-H2 Emphasis Emphasis, aka italics, with *asterisks* or _underscores_. Strong emphasis, aka bold, with **asterisks** or __underscores__. Combined emphasis with **asterisks and _underscores_**. Strikethrough uses two tildes. ~~Scratch this.~~ Emphasis, aka italics, with asterisks or underscores. Strong emphasis, aka bold, with asterisks or underscores. Combined emphasis with asterisks and underscores. Strikethrough uses two tildes. Scratch this. Lists(In this example, leading and trailing spaces are shown with with dots: ⋅) 1. First ordered list item 2. Another item ⋅⋅* Unordered sub-list. 1. Actual numbers don't matter, just that it's a number ⋅⋅1. Ordered sub-list 4. And another item. ⋅⋅⋅You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown). ⋅⋅⋅To have a line break without a paragraph, you will need to use two trailing spaces.⋅⋅ ⋅⋅⋅Note that this line is separate, but within the same paragraph.⋅⋅ ⋅⋅⋅(This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.) * Unordered list can use asterisks - Or minuses + Or pluses First ordered list item Another item Unordered sub-list. Actual numbers don't matter, just that it's a number Ordered sub-list And another item. You can have properly indented paragraphs within list items. Notice the blank line above, and the leading spaces (at least one, but we'll use three here to also align the raw Markdown). To have a line break without a paragraph, you will need to use two trailing spaces. Note that this line is separate, but within the same paragraph. (This is contrary to the typical GFM line break behaviour, where trailing spaces are not required.) Unordered list can use asterisks Or minuses Or pluses Links There are two ways to create links.[I'm an inline-style link](https://www.google.com) [I'm an inline-style link with title](https://www.google.com "Google's Homepage") [I'm a reference-style link][Arbitrary case-insensitive reference text] [I'm a relative reference to a repository file](../blob/master/LICENSE) [You can use numbers for reference-style link definitions][1] Or leave it empty and use the [link text itself]. URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com or <http://www.example.com> and sometimes example.com (but not on Github, for example). Some text to show that the reference links can follow later. [arbitrary case-insensitive reference text]: https://www.mozilla.org [1]: http://slashdot.org [link text itself]: http://www.reddit.com I'm an inline-style link I'm an inline-style link with title I'm a reference-style link I'm a relative reference to a repository file You can use numbers for reference-style link definitions Or leave it empty and use the link text itself. URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com or http://www.example.com and sometimes example.com (but not on Github, for example). Some text to show that the reference links can follow later. Images Here's our logo (hover to see the title text): Inline-style: ![alt text](https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 1") Reference-style: ![alt text][logo] [logo]: https://github.com/adam-p/markdown-here/raw/master/src/common/images/icon48.png "Logo Title Text 2" Here's our logo (hover to see the title text): Inline-style: Reference-style: Code and Syntax Highlighting Code blocks are part of the Markdown spec, but syntax highlighting isn't. However, many renderers -- like Github's and Markdown Here -- support syntax highlighting. Which languages are supported and how those language names should be written will vary from renderer to renderer. Markdown Here supports highlighting for dozens of languages (and not-really-languages, like diffs and HTTP headers); to see the complete list, and how to write the language names, see the highlight.js demo page. Inline `code` has `back-ticks around` it. Inline code has back-ticks around it. Blocks of code are either fenced by lines with three back-ticks ```, or are indented with four spaces. I recommend only using the fenced code blocks -- they're easier and only they support syntax highlighting.```javascript var s = "JavaScript syntax highlighting"; alert(s); ``` ```python s = "Python syntax highlighting" print s ``` ``` No language indicated, so no syntax highlighting. But let's throw in a <b>tag</b>. ``` var s = 'JavaScript syntax highlighting'; alert(s); s = "Python syntax highlighting" print s No language indicated, so no syntax highlighting in Markdown Here (varies on Github). But let's throw in a <b>tag</b>. Tables Tables aren't part of the core Markdown spec, but they are part of GFM and Markdown Here supports them. They are an easy way of adding tables to your email -- a task that would otherwise require copy-pasting from another application. Colons can be used to align columns. | Tables | Are | Cool | | ------------- | :-----------: | ----: | | col 3 is | right-aligned | $1600 | | col 2 is | centered | $12 | | zebra stripes | are neat | $1 | There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown. | Markdown | Less | Pretty | | -------- | --------- | ---------- | | *Still* | `renders` | **nicely** | | 1 | 2 | 3 | Colons can be used to align columns. Tables Are Cool col 3 is right-aligned$1600 col 2 is centered$12 zebra stripes are neat$1 There must be at least 3 dashes separating each header cell. The outer pipes (|) are optional, and you don't need to make the raw Markdown line up prettily. You can also use inline Markdown. Markdown Less Pretty Still renders nicely 1 2 3 Blockquotes> Blockquotes are very handy in email to emulate reply text. > This line is part of the same quote. Quote break. > This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can *put* **Markdown** into a blockquote. Blockquotes are very handy in email to emulate reply text. This line is part of the same quote. Quote break. This is a very long line that will still be quoted properly when it wraps. Oh boy let's keep writing to make sure this is long enough to actually wrap for everyone. Oh, you can put Markdown into a blockquote. Inline HTML You can also use raw HTML in your Markdown, and it'll mostly work pretty well.<dl> <dt>Definition list</dt> <dd>Is something people use sometimes.</dd> <dt>Markdown in HTML</dt> <dd>Does *not* work **very** well. Use HTML <em>tags</em>.</dd> </dl> Definition list Is something people use sometimes. Markdown in HTML Does *not* work **very** well. Use HTML tags. Horizontal Rule Three or more... [![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#-) Hyphens *** Asterisks ___ Underscores Three or more... Hyphens Asterisks Underscores Line Breaks My basic recommendation for learning how line breaks work is to experiment and discover -- hit <Enter> once (i.e., insert one newline), then hit it twice (i.e., insert two newlines), see what happens. You'll soon learn to get what you want. "Markdown Toggle" is your friend. Here are some things to try out: Here's a line for us to start with. This line is separated from the one above by two newlines, so it will be a *separate paragraph*. This line is also a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the *same paragraph*. Here's a line for us to start with. This line is separated from the one above by two newlines, so it will be a separate paragraph. This line is also begins a separate paragraph, but... This line is only separated by a single newline, so it's a separate line in the same paragraph.(Technical note: Markdown Here uses GFM line breaks, so there's no need to use MD's two-space line breaks.) YouTube Videos They can't be added directly but you can add an image with a link to the video like this:<a href="http://www.youtube.com/watch?feature=player_embedded&v=YOUTUBE_VIDEO_ID_HERE " target="_blank"><img src="http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg" alt="IMAGE ALT TEXT HERE" width="240" height="180" border="10" /></a> Or, in pure Markdown, but losing the image sizing and border:[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/YOUTUBE_VIDEO_ID_HERE/0.jpg)](http://www.youtube.com/watch?v=YOUTUBE_VIDEO_ID_HERE) This is a paragraph. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. This is an H1 Quisque facilisis erat a dui. Nam malesuada ornare dolor. Cras gravida, this is marked text ornare, erat elit consectetuer erat, id egestas pede nibh eget odio. Proin tincidunt, velit vel porta elementum, magna diam molestie sapien, non aliquet massa pede eu diam. Aliquam iaculis. Fusce et ipsum et nulla tristique facilisis. This is an H2 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. This is an H3 Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. This is an H4 Quisque facilisis erat a dui. Nam malesuada ornare dolor. Cras gravida, diam sit amet rhoncus ornare, erat elit consectetuer erat, id egestas pede nibh eget odio. Proin tincidunt, velit vel porta elementum, magna diam molestie sapien, non aliquet massa pede eu diam. Aliquam iaculis. Quoting Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Creativity is allowing yourself to make mistakes. Design is knowing which ones to keep. - Scott Adams Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Unordered Lists Donec non tortor in arcu mollis feugiat Lorem ipsum dolor sit amet, consectetuer adipiscing elit Donec id eros eget quam aliquam gravida Vivamus convallis urna id felis Nulla porta tempus sapien Ordered Lists Donec non tortor in arcu mollis feugiat Lorem ipsum dolor sit amet, consectetuer adipiscing elit Donec id eros eget quam aliquam gravida Vivamus convallis urna id felis Nulla porta tempus sapien Video Embeds Code Blocks Blocks of code are either fenced by lines with three back-ticks, or are indented with four spaces.<!-- Some example CSS code --> body { color:red; } window.$docsify = { coverpage: true, // Custom file name coverpage: 'cover.md', // mutiple covers coverpage: ['/', '/zh-cn/'], // mutiple covers and custom file name coverpage: { '/': 'cover.md', '/zh-cn/': 'cover.md' } }; Tables Table with thead, tfoot, and tbody Header content 1 Header content 2 Body content 1 Body content 2 Footer content 1 Footer content 2 Note: Both of the features you used above are parts of the Document Object Model (DOM) API, which allows you to manipulate documents. Important: In this article, try entering the example code lines into your JavaScript console to see what happens. For more details on JavaScript consoles, see Discover browser developer tools.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Intro To NodeJS Enter the NodeJS Node.js is an open-source and cross-platform JavaScript runtime environment. It is a popular tool for almost any kind of project! Node.js runs the V8 JavaScript engine, the core of Google Chrome, outside of the browser. This allows Node.js to be very performant. A Node.js app runs in a single process, without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm. When Node.js performs an I/O operation, like reading from the network, accessing a database or the filesystem, instead of blocking the thread and wasting CPU cycles waiting, Node.js will resume the operations when the response comes back. This allows Node.js to handle thousands of concurrent connections with a single server without introducing the burden of managing thread concurrency, which could be a significant source of bugs. Node.js has a unique advantage because millions of frontend developers that write JavaScript for the browser are now able to write the server-side code in addition to the client-side code without the need to learn a completely different language. In Node.js the new ECMAScript standards can be used without problems, as you don't have to wait for all your users to update their browsers - you are in charge of deciding which ECMAScript version to use by changing the Node.js version, and you can also enable specific experimental features by running Node.js with flags. A Vast Number of Libraries npm with its simple structure helped the ecosystem of Node.js proliferate, and now the npm registry hosts over 1,000,000 open source packages you can freely use. An Example Node.js Application The most common example Hello World of Node.js is a web server: This code first includes the Node.js http module. Node.js has a fantastic standard library, including first-class support for networking. The createServer() method of http creates a new HTTP server and returns it. The server is set to listen on the specified port and host name. When the server is ready, the callback function is called, in this case informing us that the server is running. Whenever a new request is received, the request event is called, providing two objects: a request (an http.IncomingMessage object) and a response (an http.ServerResponse object). Those 2 objects are essential to handle the HTTP call. The first provides the request details. In this simple example, this is not used, but you could access the request headers and request data. The second is used to return data to the caller. In this case with: JScopy res.statusCode = 200 we set the statusCode property to 200, to indicate a successful response. We set the Content-Type header: JScopy res.setHeader('Content-Type', 'text/plain') and we close the response, adding the content as an argument to end(): JScopy res.end('Hello World\n') Node.js Frameworks and Tools Node.js is a low-level platform. In order to make things easy and exciting for developers, thousands of libraries were built upon Node.js by the community. Many of those established over time as popular options. Here is a non-comprehensive list of the ones worth learning: AdonisJS: A TypeScript-based fully featured framework highly focused on developer ergonomics, stability, and confidence. Adonis is one of the fastest Node.js web frameworks. Egg.js: A framework to build better enterprise frameworks and apps with Node.js & Koa. Express: It provides one of the most simple yet powerful ways to create a web server. Its minimalist approach, unopinionated, focused on the core features of a server, is key to its success. Fastify: A web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. Fastify is one of the fastest Node.js web frameworks. FeatherJS: Feathers is a lightweight web-framework for creating real-time applications and REST APIs using JavaScript or TypeScript. Build prototypes in minutes and production-ready apps in days. Gatsby: A React-based, GraphQL powered, static site generator with a very rich ecosystem of plugins and starters. hapi: A rich framework for building applications and services that enables developers to focus on writing reusable application logic instead of spending time building infrastructure. koa: It is built by the same team behind Express, aims to be even simpler and smaller, building on top of years of knowledge. The new project born out of the need to create incompatible changes without disrupting the existing community. Loopback.io: Makes it easy to build modern applications that require complex integrations. Meteor: An incredibly powerful full-stack framework, powering you with an isomorphic approach to building apps with JavaScript, sharing code on the client and the server. Once an off-the-shelf tool that provided everything, now integrates with frontend libs React, Vue, and Angular. Can be used to create mobile apps as well. Micro: It provides a very lightweight server to create asynchronous HTTP microservices. NestJS: A TypeScript based progressive Node.js framework for building enterprise-grade efficient, reliable and scalable server-side applications. Next.js: React framework that gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. Nx: A toolkit for full-stack monorepo development using NestJS, Express, React, Angular, and more! Nx helps scale your development from one team building one application to many teams collaborating on multiple applications! Sapper: Sapper is a framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing. Offers SSR and more! Socket.io: A real-time communication engine to build network applications. Strapi: Strapi is a flexible, open-source Headless CMS that gives developers the freedom to choose their favorite tools and frameworks while also allowing editors to easily manage and distribute their content. By making the admin panel and API extensible through a plugin system, Strapi enables the world's largest companies to accelerate content delivery while building beautiful digital experiences. Extended Version: Introduction to JavaScript JavaScript is dynamically typed single-threaded interpreted languages for the Web. That means if you are doing web development, you can use this language to perform some operating on the web page, like running some JavaScript code when a button is clicked by the user. JavaScript is a dynamically typed language which means a variable can hold any data type like String or Number in its lifetime and JavaScript interpreter won't complain about it. It's single-threaded which means your JavaScript code runs synchronously or sequentially line by line. It's interpreted which means you don't need to compile your JavaScript code. JavaScript is interactive, which means you can directly feed JavaScript code to the interpreter and it will be executed immediately. You can try this by opening DevTools in the browser (_in Chrome, press _*command** + **option** + **i*) or right-click anywhere on the page and click inspect. Then go to the console tab, here you can type any valid JavaScript code and press enter to run it. Use shift + enter to add a new-line in your code.(interacting with JavaScript interpreter) Every browser ships a JavaScript Interpreter also called a JavaScript Engine. V8 is the JavaScript engine designed by Google and used in the Google Chrome browser while SpiderMonkey is a JavaScript engine developed by Mozilla for their Firefox browser. Since JavaScript engine designed by every browser is different, ECMA standardizes features of JavaScript. This standard is known as ECMAScript ( pronounced as ek-ma-script). Whenever ECMA adds a feature to this JavaScript standard, the browser has to add it in their JavaScript engine to stay in the competition ( though this process is very slow). JavaScript is a very easy language to learn and fun to write. Every year, new features are added to ECMAScript which brings JavaScript one more step closer to dominate the planet. The latest major revision of JavaScript is ES6 or ECMAScript 6 or ECMAScript 2015 which has dumped a ton of features to make it more fun to code in. At the moment, JavaScript supports the OOP paradigm very well and can be used in functional programming as well. Mozilla is an open-source foundation that documents JavaScript very well on their developer documentation AKA Mozilla Developer Network or MDN. It is one of the top online destinations to learn JavaScript, though there are other online resources as well. If you want to take a look at the JavaScript specifications and learn simple tutorials, visit MDN Documentation. JavaScript is sometimes abbreviated as JS or .js/.JS ( dot J S) to state that an entity is related to JavaScript, like Node.js or ReactJS or AngularJS. But in no ways, JavaScript is related to Java, or so you think 👻. If you need a history lesson about JavaScript and its evolution, watch this amazing video. https://www.youtube.com/watch?v=Sh6lK57Cuk4 Assuming that you are familiar with JavaScript and gained a good amount of knowledge, we can move forward. But if you don't know JavaScript at all, learn basic JavaScript from the MDN documentation I explained earlier. Because learning about Node.js without knowledge of JavaScript is like understanding web development without HTML. What is server-side JavaScript? JavaScript is a single-threaded language, it knows how to get things done one at a time. It can't do asynchronous tasks or run JavaScript code in multiple threads for efficiency. It just knows about JavaScript as defined in ECMAScript specification and nothing more. Since JavaScript is used on the web, it needs to be secure. Hence, using JavaScript, you can't access the computer it is running on, like File System, IO, Networking, etc. and neither ECMAScript has specifications for that. So it is up to the browser vendors to extend JavaScript engine with APIs that can do other things. For example, DOM API is responsible to print an HTML code into actual pixels on the screen, I have explained this process in my Medium article. Also, the XMLHttpRequest API gives us the ability to send network requests to fetch data from a remote server in the background. These sorts of APIs are responsible to perform other operations that JavaScript is not designed to perform. These APIs are provided by the browser and they are called Web APIs. These APIs are written in some Low-Level languages like C or C++ but their interface is made available through JavaScript. These Web APIs sometimes do their job in separate thread allowing other JavaScript code to run normally while the job is running in the background. Once the job is done, it then informs the main JavaScript thread. So through JavaScript, you are executing C++ code and returning result back to the JavaScript, that doesn't sound so difficult. For example, [setTimeout(callback, delay)](https://www.w3schools.com/jsref/met_win_settimeout.asp) function is not part of ECMAScript specification, it is provided by the browser to perform an asynchronous operation. The callback function is executed in the main JavaScript thread once delay milliseconds has elapsed.(an oversimplification of how JavaScript runs in a browser) So far we know that JavaScript is essential in a browser. But if you think about JavaScript engine alone, it can exist anywhere. You can take the V8 JavaScript engine and install it on your computer ( let's call it as a server). With some fiddling, you can feed JavaScript code to it and it will run that code for you and may return the result. In theory, it looks pretty simple. The concept of server-side JavaScript comes from this simple idea. You can take any JavaScript engine, wrap inside an application that gives a clean interface to take the user's JavaScript code and execute it in the JavaScript engine. You can also provide APIs to perform operations like File System IO, Networking, etc. which do not run on JavaScript engine.(an oversimplification of how JavaScript runs on a server) Ryan Dahl took this idea and made Node.js. To understand more about how a JavaScript engine works in a browser, you should read my article on How JavaScript engine works in browser and Node. This article also explain concept of Web APIs in depth. How Node.js works? Sometimes, Node.js is also called simply Node or node. Node.js is a framework that contains the V8 JavaScript engine, the standard library of packages, and some binaries. In reality, it is more complex than that as explained in the below diagram ( follow the link for more details).(Source: Stackoverflow) Like Web APIs in the browser, Node.js has a standard library that contains JavaScript packages ( we will learn about packages later) which may also provide an interface to low-level APIs. For example, Node.js comes with fs package which contains readFile function among many. This function reads the file on the disk of the machine and returns file content back. Most of these packages contain code written in a low-level programming language to communicate with the device, like for file system access. These packages export JavaScript functions and other types to run this code. Since JavaScript can not talk to C++ or some other language, Node.js has to create a binding to facilitate this communication. The process to create such packages is very tricky, but it is explained here in-depth. Node.js uses different threads to perform low-level non-JavaScript time-taking operations. This way, our JavaScript is not blocked while a time taking operation like reading a file is in progress. Since these operations are running in the background once initiated, we need a confirmation or a callback when the operation is finished. This callback is a JavaScript function that will execute as soon as the operation is finished. const fs = require('fs'); // fs is built-in packagefs.readFile('/path/to/file.txt', function(error, data){ // if error is not empty, show error log // read data and do something with it }); The Node.js architecture is very complex and made of different parts as seen in the earlier diagram. It also contains an event loop that facilitates the execution of these callback functions. You should watch the below video on the event loop, though it is in the context of the browser but things are pretty similar in Node.js as well. This will clear your remaining doubts. Installing Node.js You should install Node.js from their official website at nodejs.org. If you are using Windows, Mac OS, or Linux, you can get precompiled binaries and installers. The best way to go is by using an installer. When you install Node.js, you get node and npm binaries added to your path. That means, now you can use node and npm command. We will talk about npm later, but for now, let's focus on the node. Using -v or --version flag, we can check the version of the Node installed. The latest node will have the latest V8 engine, hence latest JavaScript features. If you need the flexibility to change Node version at any given time, in that case, you should not install Node.js using above method. Instead, you should use Node Version Manager or NVM. Here is the list of Node.js releases with V8 engine versions. Like we saw in DevTools of the browser, using the simple command node will open a JavaScript interpreter in the terminal. This way we can run some simple JavaScript code to amuse yourself.(node interpreter) Running JavaScript code with Node.js Now that we have a good understanding of what Node.js is and how JavaScript engine works, we can start messing with it. Using an interpreter we can perform some basic arithmetics and other basic stuff. But most of the time, your actual JavaScript code will be in a .js file. Instead of giving one line at a time to the interpreter, we need to give whole file content at once. We can do that by using node /path/to/file.js command.( hello-world.js) In the above example, we have created hello-world.js file and it contains hello function. This function is executed after it was defined in the same file. Using the terminal, we executed node ./hello-world.js command. node will pick up hello-world.js file from the directory where the terminal is opened and run it using the V8 JavaScript engine. Since node can only execute .js files, adding .js extension to the file path is optional. If we provide a directory path instead of file path to node, Node.js will try to resolve index.js file inside that directory.(executing index.js in the current directory with Node) Importing scripts in the program Normally our application is broken down to different parts. For example, if a set of functions are used over and over, we would like them to be contained in a separate file and import that file wherever those functions are to be used. Node.js supports this functionality natively. When you import a file inside another file, that file is called a module. Node.js uses the CommonJS module system syntax to import modules and packages. Though ES6+ supports new module system, it is yet to be implemented in Node. Let's create a lib directory and place math.js file inside it. This file contains some common math functions like add and multiply. We will import this file inside calculate.js file situated in the main directory. Hence math.js is a module, since we are importing it and not executing it directly with Node. To import a module, we need to use require function provided by the Node.js and available globally everywhere in the program. This function takes a relative or an absolute path of the module file and returns what module is exporting. Hence, we need to save it inside a variable.// calculate.js var math = require( './lib/math.js' ); // .js is optional require() statement sometimes also called as import statement. Now let's take a look at math.js file. We need to provide AKA export some values to the require() function call. This is done using exports variable. This variable is also globally available everywhere. This variable is actually an object which is empty {} at the beginning. When we import this module using require function, this is the object require() call will return.// calculate.js var math = require( './lib/math' );console.log(math); // {} Since we know that exports is an object that will be exported from the module, we can stuff it with whatever we want. As objects go, an object is a collection of key-value pairs. So let's add some math functions to it.// lib/math.js// add add function to exports exports.add = function( num1, num2 ) { return num1 + num2 }; From math module, we are exporting add function which returns the sum of the two numbers ( arguments). Let's see what math variable looks like.// calculate.js var math = require( './lib/math' );console.log(math); { add: [Function] } It shows that math variable is an object that contains add key which has a Function value. Let's execute that function and see the result.// calculate.js var math = require( './lib/math' );// add 1 + 2 var result = math.add(1, 2); console.log( result ); // 3 What the heck is module.exports then? I kind of skipped over this part so that you can understand module import with ease. I have a simple question, what if my math module exports only one function like add but I don't want to export it inside an object. This is the only function my module is exporting, so I want require() call to return this function only so that I can start using it like below.// calculate.js var math = require( './lib/math' );// add 1 + 2 var result = math(1, 2); // math is a function console.log( result ); // 3 This is where module global variable comes into the picture. Like exports, module is also globally available everywhere. module is an object and it contains information about module ( auto injected by Node.js in key-value pairs). The important key in this object we should know about is exports. exports variable inside a module points to exports property on the module object, as you can prove in the below test.// lib/math.js console.log(exports === module.exports); // true That means when we were setting exports.add, we were actually setting module.exports.add. So if we want our module to export only one function, we can just assign module.exports to that function. We could say that since exports and module.exports is the same, why not just set exports to the function. The reason is how objects are handled in JavaScript. Read this answer to explore this topic in details.// lib/math.js// export function only module.exports = function( num1, num2 ) { return num1 + num2 }; If your module import path is a directory, then require function will resolve index.js file inside it. Using this feature, you can have multiple . js files in a directory that contains different exports and you can import them inside index.js to exports them again from a single point.└── lib/ ├── index.js (import math and graph and export them) ├── math.js └── graph.js This way, the importer does not need to target individual module files in a directory. The importer can just point to index.js file.// lib/math.js exports.add = function( num1, num2 ) { return num1 + num2 };// lib/index.js var math = require('./math'); exports.add = math.add // calculate.js const lib = require('./lib'); // points to './lib/index.js' lib.add(1, 2) // 3 In Node.js, a module or a package is loaded only once ( per thread or session) even when you require() them multiple times in the program. Once loaded, it will be cached by the Node for performance enhancement. There are other tricks with CommonJS module system and sometimes we also need to be careful. Read this article to understand more about imports. Packages in Node.js A package is nothing but a directory that contains a bunch of modules. Like for example lib in our previous example can be called a package but not quite yet. The most important feature about a node package is that, from anywhere in the program, we should be able to import it, without providing a relative or an absolute path. Well, that sounds absurd. If our .js files are nested, the import path will also change. Let's say that, we have a src directory and it contains compute.js. If we need to import lib package, the import path will be ../lib.├── lib/ | ├── index.js | └── math.js └── src/ ├── compute.js // require( '../lib') └── deep/ └── nested.js // require( '../../lib') As we nest our files deeper, the import path is very difficult to track. What would be easy is instead of the relative path, we would just use lib and Node.js just finds the path to that package for us.// src/compute.js const lib = require('lib'); // points to '../lib/index.js' lib.add(1, 2) // 3 This might sound like a fantasy but it is actually very real. Node.js can do this for us, just that we need to create node_modules directory and clone lib directory inside it. This way, when we call require('lib'), it will point to the lib directory inside node_modules. Now, lib is a package. You might wonder, why they are called node_modules and not node_packages? In a conventional sense, a module is a file and package is a collection of modules. But when it comes to require function, they are ambiguous. Hence, let's stick to a common name, module. But normally, when people say node module, it is a package inside node_modules directory. But the real question is, how does Node knows where the node_modules directory is. The answer is, it doesn't. When we import a package, it searches that package inside node_modules directory of the current file path ( where import statement is written). If it doesn't find node_modules directory or the package directory, it performs a similar search in the parent directory. This continues until the last directory in the file system is reached. If it doesn't find the package, it throws Error: Cannot find module 'lib' error. Let's create node_modules directory in our project and clone lib directory there. From src/compute.js, we will call the add function as before.( package introduction) In the above example, we are importing math.js file from lib package. If we just use require('lib'), Node.js will point to index.js file inside lib package directory. If math.js is missing, require will try to resolve math/index.js file treating math as a directory. Even though packages seems easy, their management if done manually is very difficult. Like what if we needed a 3rd-party package? I mean, should we clone the remote source code and put it inside node_module directory manually? Do you know how hard that would be for multiple people in the team? And whenever package version changes, it would be a mess to update. This is where NPM comes into the picture. This whole modules and packages theory might sound familiar to you if you are a python developer. But you don't need init.py like file in Node.js 😉 What is NPM? When we installed Node.js, we also got npm command. NPM or Node Package Manager is the default package manager for Node.js. A role of a package manager is to download and install remote package, with ease. BTW, we can also install packages from a local directory. Node.js has a wide community that develop good packages for everybody to use. For example, lodash is the package that is used widely. This package contains useful utility functions like add in our earlier example. These utility functions are very well documented on their official website. When we have a remote package in our project, it is called as a dependency since our project depends on it. We need to keep track of our dependencies or at least list them down somewhere. We list all our dependencies inside a package.json file which is a JSON file that contains some information about our project and dependencies it needs. This file is essential for NPM. To create this file using npm, use npm init command. This command will ask you some question to fill project-specific data in package.json and eventually create package.json file. You can bypass the questions using -y flag.(Initializing package.json) Note dependencies section in the package.json file, it is empty at the moment. This means, our project at the moment does not depend on any of the remote packages. To install a package, we use npm install <packagename> command. For example, to install lodash package, we use npm install --save lodash command. Using --save flag, we can make entry of this package inside dependencies section of the package.json file. This command will do the following things. At first, it searches for this package on [registry.npm.com](http://registry.npmjs.org/) which contains the database of all packages. You can see the documentation of a package by visiting [https://www.npmjs.com/package/<packagename>](https://www.npmjs.com/package/lodash) URL. Then it downloads the compressed zip ( or tar) file that contains all the source code of the package. If a version of the package was not specified in the command, it will download the latest version. Then it adds the package entry to the dependencies section of package.json with the version of the package. If the entry of the package already exists, it will just override the version of the package downloaded. Then it creates node_modules folder in the same directory if it doesn't already exist. Then it will copy all the files from the downloaded compressed file in the directory with the name of the package inside node_modules. Let's actually install lodash package and see how node_modules and package.json file looks like after the install.(npm install -- save lodash) From the above example, npm installed the version 4.17.15 of the lodash. This type of version number system is called as Semantic Versioning. We can also specify a specific version of a package to install using the command like npm install --save lodash@4.17.10. Now that we have installed lodash, let's use its _.toUpper function to change the case of a string. But first, we need to import the package.// src/transform.js var lodash = require( 'lodash' );var result = lodash.toUpper( 'hello world!' ); console.log( result ); // HELLO WORLD! When we run this file using the command node src/transform.js, we get HELLO WORLD! printed in the terminal. When you install a package, NPM also creates package-lock.json file if not already present. This file contains a list of dependency packages with their versions that your project has installed as well as dependencies of those packages ( because a package might use other packages and so on). This file including package.json should be tracked by your VCS while node_module directory should be ignored ( reasons explained later). NPM and package management is far more sophisticated (and for good) than this but we will discuss it later in details. Built-in Packages AKA Built-in Modules Node.js ships with a collection of built-in packages called as a Node Standard Library. These packages are essential to perform low-level operations like File System I/O and Networking. We do not have to install them using NPM. Since these packages contain code in a low-level programming language tailored to a specific version of Node.js, they have to be shipped as a part of the installation process. Here is a list of built-in modules in Node.js. These packages do not exist on disk like lodash. They are compiled into low-level or intermediate stuff ( explained here) but their sources are listed here.[fs](https://nodejs.org/api/fs.html) package is used to perform File System operations like file read and write while [path](https://nodejs.org/api/path.html) package is used to resolve a file or directory path on the system. Let's use these packages to demonstrate a cool example.├── res | └── hello-world.txt └── fs-example.js According to the above project structure, we have hello-world.txt file which contains Hello World! text. Using fs-example.js, we want to read the text in the file and log in to the console.(Sample fs and path module introduction) In the above program, we imported the fs and path built-in modules. When we require(name) a package, Node.js first searches for the package name in the built-in packages. If it doesn't find it in the standard library, then it searches for it in node_modules as explained earlier. __dirname is a globally available variable that resolves to the absolute path of the current file on the disk. [path.resolve](https://nodejs.org/api/path.html#path_path_resolve_paths) function takes multiple path segments and joins them. This is a safe way to create an absolute path of a file on the disk, as Windows and Unix systems use different path delimiter. You can also use a relative path like var filePath = './res/hello-world.txt'; in the above example but path.resolve is safer. process is a globally available object that contains information about environment variables and current process context in general. Unlike __dirname, [process.cwd()](https://nodejs.org/api/process.html#process_process_cwd) function returns the path of the directory from where the node command was executed in the terminal (or the current directory in the terminal). Let's talk about the example in detail. Inside fs-example.js file, we imported built-in modules fs and path. Then we constructed a filePath which points to hello-world.txt on the disk.[fs.readFile](https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback) function takes below arguments in series filePath: A absolute or relative path to the file we are trying to read. options: An object that contains a configuration about reading. In the above example, we set encoding to utf-8 which converts binary data to Text format. This will convert file content to Text. callback: Sync file read operation using readFile function is asynchronous, we need a callback function to execute when the file is read completely. This function will receive read error ( if any) as the first argument and file data as the second argument. Notice the console log. The first -end-of-the-program- statement got printed as fs.readFile was reading the file in the background. Once file reading was completed, the callback function was called. Node.js can also perform synchronous (blocking) operations. For example, using [fs.readFileSync](https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options), we can block the JavaScript thread until the file is read. This way, we can make sure, JavaScript code run sequentially.( Reading a file synchronously) Creating an HTTP server in Node.js Node.js can do anything, literally anything. Node.js has built-in [http](https://nodejs.org/api/http.html) module as well as [https](https://nodejs.org/api/https.html) module to create an HTTP/HTTPS server. But their implementation is kind of hard. ExpressJS is a 3rd-party package that wraps the built-in http module and provide a cleaner interface to create an HTTP server. This package is listed on NPM registry under [express](https://www.npmjs.com/package/express) name. Let's create a basic HTTP server. First, we need to install express package using NPM. npm install --save express Then we will import this package and create a basic HTTP server inside server.js file. We will follow their startup documentation.( Sample express HTTP server) When we executed server.js file with node, ExpressJS will lock the Node process as we want the server to be running forever. Now that server is running on the port 9000, we can open the browser and access URL <http://localhost:9000/> which will execute the .get callback.(<http://localhost:9000/>) This was just a basic example of how we can create an HTTP server in Node.js. But with express.js, we can create more complex servers which can send HTML file content using response.sendFile(filePath) function or send JSON using response.json(object) function. We can also create an endpoint that serves static files like images from the disk using middlewares. To stop the server, we need to stop the locked Node.js process. We can do that by pressing ctrl+c in the terminal. But what if we need to actually run the server on the production literally forever. In that case, we can't have terminal open for years. This is where the process managers comes in. PM2 is one of the best process managers that can run a Node process in the background. When you install it, it will give you a clean command-line interface to start a Node.js process and PM2 will monitor it. Execute a Bash command from Node.js If you make Node.js your life and want to do everything from Node, then this topic is very important. Let's say that from a JavaScript program, you want to execute a BASH command. A Bash command would be echo Hello World!. You can try this command in the terminal and it will print Hello World!. Node.js provides a built-in [child_process](https://nodejs.org/api/child_process.html) command to run Bash command in a separate process. [child_process.exec](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback) function takes a Bash command and executes it. It takes an optional callback function to execute ( with some process information) when the process is terminated. Let's create a echo.js file that executes echo Hello World! Bash command.( child_process example) In the above program, the callback function to child_process.exec receives the standard output of the program. child_process module can do many things, like execute a Bash file using [child_process.execFile](https://nodejs.org/api/child_process.html#child_process_child_process_execfile_file_args_options_callback) function. It also supports synchronous variants to run a bash command synchronously, like [child_process.execSync](https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options) function. How to ship your code to Production? Now that we have a good understanding of Node.js and NPM, we can move forward to this most important topic. package.json and package-lock.json files are very important as they contain information about dependencies our project has. Those dependencies are stored inside node_modules directory by the NPM. So if our project is managed using a VCS like Git then should we commit all our code? The answer is, 😱 NOOOOOOOOOOO. node_modules directory can be very large as it contains deeply nested dependencies. Hence it should be ignored by the VCS. Use .gitignore file to do that..gitignore\ node_modules But then when your buddy takes the clone or a pull of the project, he/she won't get node_modules. Nothing to worry about here because NPM can take care of that. When we used npm install <packagename> command for the first time, NPM created node_modules directory and install packagename package. Using npm install command ( without a package name), NPM will look at pakage.json to install all the dependencies listed inside it. Actually, since NPM v.5, npm install command looks at package-lock.json command to install the dependencies since it contains the exact versions of the packages and their dependencies (which were installed by the developer of the project). This minimizes the conflict of versions between the development machine and production machine. By ignoring node_modules, we are actually saving a lot of time and bandwidth of transferring the project from a development machine to production.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Installing Node Android Android support is still experimental in Node.js, so precompiled binaries are not yet provided by Node.js developers. However, there are some third-party solutions. For example, Termux community provides terminal emulator and Linux environment for Android, as well as own package manager and extensive collection of many precompiled applications. This command in Termux app will install the last available Node.js version: pkg install nodejs Currently, Termux Node.js binaries are linked against system-icu (depending on libicu package). Arch Linux Node.js and npm packages are available in the Community Repository. pacman -S nodejs npm CentOS, Fedora and Red Hat Enterprise Linux Node.js is available as a module called nodejs in CentOS/RHEL 8 and Fedora. dnf module install nodejs:<stream> where <stream> corresponds to the major version of Node.js. To see a list of available streams: dnf module list nodejs For example, to install Node.js 12: dnf module install nodejs:12 For CentOS/RHEL 7 Node.js is available via Software Collections. Alternatives These resources provide packages compatible with CentOS, Fedora, and RHEL. Node.js snaps maintained and supported at https://github.com/nodejs/snap Node.js binary distributions maintained and supported by NodeSource Debian and Ubuntu based Linux distributions Node.js binary distributions are available from NodeSource. Alternatives Packages compatible with Debian and Ubuntu based Linux distributions are available via Node.js snaps. fnm Fast and simple Node.js version manager built in Rust used to manage multiple released Node.js versions. It allows you to perform operations like install, uninstall, switch Node versions automatically based on the current directory, etc. To install fnm, use this install script. fnm has cross-platform support (macOS, Windows, Linux) & all popular shells (Bash, Zsh, Fish, PowerShell, Windows Command Line Prompt). fnm is built with speed in mind and compatibility support for .node-version and .nvmrc files. FreeBSD The most recent release of Node.js is available via the www/node port. Install a binary package via pkg: pkg install node Or compile it on your own using ports: cd /usr/ports/www/node && make install Gentoo Node.js is available in the portage tree. emerge nodejs IBM i LTS versions of Node.js are available from IBM, and are available via the 'yum' package manager. The package name is nodejs followed by the major version number (for instance, nodejs12, nodejs14 etc) To install Node.js 14.x from the command line, run the following as a user with *ALLOBJ special authority: yum install nodejs14 Node.js can also be installed with the IBM i Access Client Solutions product. See this support document for more details macOS Download the macOS Installer directly from the nodejs.org web site. If you want to download the package with bash: curl "https://nodejs.org/dist/latest/node-${VERSION:-$(wget -qO- https://nodejs.org/dist/latest/ | sed -nE 's|.*>node-(.*)\.pkg</a>.*|\1|p')}.pkg" > "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" Alternatives Using Homebrew: brew install node Using MacPorts: port install nodejs<major version> # Example port install nodejs7 Using pkgsrc: Install the binary package: pkgin -y install nodejs Or build manually from pkgsrc: cd pkgsrc/lang/nodejs && bmake install n n is a simple to use Node.js version manager for Mac and Linux. Specify the target version to install using a rich syntax, or select from a menu of previously downloaded versions. The versions are installed system-wide or user-wide, and for more targeted use you can run a version directly from the cached downloads. See the homepage for install methods (boostrap, npm, Homebrew, third-party), and all the usage details. If you already have npm then installing n and then the newest LTS node version is as simple as: npm install -g n n lts NetBSD Node.js is available in the pkgsrc tree: cd /usr/pkgsrc/lang/nodejs && make install Or install a binary package (if available for your platform) using pkgin: pkgin -y install nodejs Nodenv nodenv is a lightweight node version manager, similar to nvm. It's simple and predictable. A rich plugin ecosystem lets you tailor it to suit your needs. Use nodenv to pick a Node version for your application and guarantee that your development environment matches production. Nodenv installation instructions are maintained on its Github page. Please visit that page to ensure you're following the latest version of the installation steps. nvm Node Version Manager is a bash script used to manage multiple released Node.js versions. It allows you to perform operations like install, uninstall, switch version, etc. To install nvm, use this install script. On Unix / OS X systems Node.js built from source can be installed using nvm by installing into the location that nvm expects: env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" After this you can use nvm to switch between released versions and versions built from source. For example, if the version of Node.js is v8.0.0-pre: nvm use 8 Once the official release is out you will want to uninstall the version built from source: nvm uninstall 8 nvs Windows The nvs version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems To install nvs on Windows go to the release page here and download the MSI installer file of the latest release. You can also use chocolatey to install it: choco install nvs macOS,UnixLike You can find the documentation regarding the installation steps of nvs in macOS/Unix-like systems here Usage After this you can use nvs to switch between different versions of node. To add the latest version of node: nvs add latest Or to add the latest LTS version of node: nvs add lts Then run the nvs use command to add a version of node to your PATH for the current shell:$ nvs use lts PATH -= %LOCALAPPDATA%\nvs\default PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 To add it to PATH permanently, use nvs link: nvs link lts OpenBSD Node.js is available through the ports system./usr/ports/lang/node Using pkg_add on OpenBSD: pkg_add node openSUSE and SLE Node.js is available in the main repositories under the following packages: openSUSE Leap 15.2: nodejs10, nodejs12, nodejs14 openSUSE Tumbleweed: nodejs16 SUSE Linux Enterprise Server (SLES) 12: nodejs10, nodejs12, and nodejs14 (The "Web and Scripting Module" must be enabled.) SUSE Linux Enterprise Server (SLES) 15 SP2: nodejs10, nodejs12, and nodejs14 (The "Web and Scripting Module" must be enabled.) For example, to install Node.js 14.x on openSUSE Leap 15.2, run the following as root: zypper install nodejs14 Different major versions of Node can be installed and used concurrently. SmartOS and illumos SmartOS images come with pkgsrc pre-installed. On other illumos distributions, first install pkgsrc, then you may install the binary package as normal: pkgin -y install nodejs Or build manually from pkgsrc: cd pkgsrc/lang/nodejs && bmake install Snap Node.js snaps are available as node on the Snap store. Solus Solus provides Node.js in its main repository. sudo eopkg install nodejs Void Linux Void Linux ships Node.js stable in the main repository. xbps-install -Sy nodejs Windows Download the Windows Installer directly from the nodejs.org web site. Alternatives Using Chocolatey: cinst nodejs # or for full install with npm cinst nodejs.install Using Scoop: scoop install nodejs
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Kill a Process in Linux How to Kill a Process in Linux Learn how to kill errant processes in this tutorial. Picture this: You've launched an application (be it from your favorite desktop menu or from the command line) and you start using that launched app, only to have it lock up on you, stop performing, or unexpectedly die. You try to run the app again, but it turns out the original never truly shut down completely. What do you do? You kill the process. But how? Believe it or not, your best bet most often lies within the command line. Thankfully, Linux has every tool necessary to empower you, the user, to kill an errant process. However, before you immediately launch that command to kill the process, you first have to know what the process is. How do you take care of this layered task? It's actually quite simple...once you know the tools at your disposal. Let me introduce you to said tools. The steps I'm going to outline will work on almost every Linux distribution, whether it is a desktop or a server. I will be dealing strictly with the command line, so open up your terminal and prepare to type. Locating the process The first step in killing the unresponsive process is locating it. There are two commands I use to locate a process: top *and *ps. Top is a tool every administrator should get to know. With top, you get a full listing of currently running process. From the command line, issue top to see a list of your running processes (Figure 1). Figure 1: The top command gives you plenty of information. From this list you will see some rather important information. Say, for example, Chrome has become unresponsive. According to our top display, we can discern there are four instances of chrome running with Process IDs (PID) 3827, 3919, 10764, and 11679. This information will be important to have with one particular method of killing the process. Although top is incredibly handy, it's not always the most efficient means of getting the information you need. Let's say you know the Chrome process is what you need to kill, and you don't want to have to glance through the real-time information offered by top. For that, you can make use of the ps *command and filter the output through *grep. The ps command reports a snapshot of a current process and grep *prints lines matching a pattern. The reason why we filter *ps through grep is simple: If you issue the ps command by itself, you will get a snapshot listing of all current processes. We only want the listing associated with Chrome. So this command would look like: ps aux | grep chrome The aux options are as follows: a = show processes for all users u = display the process's user/owner x = also show processes not attached to a terminal The x option is important when you're hunting for information regarding a graphical application. When you issue the command above, you'll be given more information than you need (Figure 2) for the killing of a process, but it is sometimes more efficient than using top. Figure 2: Locating the necessary information with the ps command. Killing the process Now we come to the task of killing the process. We have two pieces of information that will help us kill the errant process: Process name Process ID Which you use will determine the command used for termination. There are two commands used to kill a process: kill -- Kill a process by ID killall -- Kill a process by name There are also different signals that can be sent to both kill commands. What signal you send will be determined by what results you want from the kill command. For instance, you can send the HUP (hang up) signal to the kill command, which will effectively restart the process. This is always a wise choice when you need the process to immediately restart (such as in the case of a daemon). You can get a list of all the signals that can be sent to the kill command by issuing kill -l. You'll find quite a large number of signals (Figure 3). Figure 3: The available kill signals. The most common kill signals are:| Signal Name| Single Value| Effect| | SIGHUP| 1| Hangup| | SIGINT| 2| Interrupt from keyboard| | SIGKILL| 9| Kill signal| | SIGTERM| 15| Termination signal| | SIGSTOP| 17, 19, 23| Stop the process| What's nice about this is that you can use the Signal Value in place of the Signal Name. So you don't have to memorize all of the names of the various signals. So, let's now use the *kill *command to kill our instance of chrome. The structure for this command would be: kill SIGNAL PID Where SIGNAL is the signal to be sent and PID is the Process ID to be killed. We already know, from our ps command that the IDs we want to kill are 3827, 3919, 10764, and 11679. So to send the kill signal, we'd issue the commands: kill -9 3827 kill -9 3919 kill -9 10764 kill -9 11679 Once we've issued the above commands, all of the chrome processes will have been successfully killed. Let's take the easy route! If we already know the process we want to kill is named chrome, we can make use of the *killall *command and send the same signal the process like so: killall -9 chrome The only caveat to the above command is that it may not catch all of the running chrome processes. If, after running the above command, you issue the ps aux|grep chrome command and see remaining processes running, your best bet is to go back to the *kill *command and send signal 9 to terminate the process by PID. Ending processes made easy As you can see, killing errant processes isn't nearly as challenging as you might have thought. When I wind up with a stubborn process, I tend to start off with the *killall *command as it is the most efficient route to termination. However, when you wind up with a really feisty process, the *kill *command is the way to go.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    How To Reinstall NPM and Node.js On Your System The Node Package Manager (usually shortened to npm) and Node.js are popular technologies among JavaScript developers. npm is the default package management utility that is installed automatically on your machine when you download and install Node.js. npm assists in building, consuming, managing, and sharing small pieces of code. On the other hand, Node.js provides a server-side environment for creating powerful applications. However, at times, npm can get corrupted, become incompatible with other programs, or just experience performance issues. In such cases, it may help to reinstall npm on your system and save yourself the hassles. Similarly, reinstalling Node.js may assist you in clearing out any performance errors. And since npm is shipped with Node.js by default, installing Node.js will also install npm on your system. How to check if reinstallation succeeded Note that after completing the reinstallation process, you can check if it was successful by running the following commands on the terminal: Then, if everything went well, the system will output your installed versions. Something like this: Since npm is usually updated more frequently than Node.js, your installation may not come with the latest npm version. So, if your installed npm version is not the latest, you can update it by running the following command: The above command will install the latest, stable npm version. However, if you want to experiment with things by using a version that will be released in the future, you can run the following: If you want to update Node.js to the latest version, you can read this article. How to reinstall npm and Node.js on Windows If the npm or Node.js running on your Windows environment is broken, you can reinstall and get the most out of them. You can use any of the following methods: Reinstalling using a Node version manager Reinstalling using a Node installer Let's talk about each of them. a) Reinstalling using a Node version manager A Node version manager is a tool you can use to install various versions of Node.js and npm and shift between them seamlessly. A popular Node version management tool you can use is nvm-windows. It's a powerful command line utility that allows you to manage multiple installations of Node.js comfortably. Before installing the utility, it is recommended to remove all the existing versions of Node.js and npm from your Windows computer. This will prevent any conflict issues when installing the software. You can uninstall them by doing the following: Go to the Windows Control Panel and uninstall the Node.js program. If any Node.js installation directories are still remaining, delete them. An example is C:\Program Files\mynodejs. If any npm install location is still remaining, delete it. An example is C:\Users\<username>\AppData\Roaming\npm. Then, once your system is clean, go to this page and download and run the latest nvm-windows installer. After it has been installed, you can start the Command Prompt or Powershell as an Administrator and use the tool to reinstall Node.js and npm. If you want to reinstall a specific Node.js version, you can run the following command: Let's say you want to reinstall Node.js version 12.18.0, you can run: If you want to reinstall the latest stable Node.js version, you can run: If you want to check the list of Node.js versions available for download, you can run: To use the installed Node.js version in your project, you can switch to it: b) Reinstalling using a Node installer Using the official Node installer is the easiest way to reinstall Node.js and npm on your Windows environment. To use this option, you can go to the Node.js download page and reinstall the latest Node.js version. It is recommended to download the version labeled LTS (Long-term Supported) because it has been tested with npm. Although the version labeled Current comes with the latest features, it may be unstable and unreliable. After selecting the version you want to download, and clicking the Windows Installer option, the installation wizard will magically complete the installation process for you. Ultimately, the installer will automatically overwrite your existing, malfunctioned Node.js version with a new one. How to reinstall npm and Node.js on macOS Before reinstalling Node.js and npm on your macOS system, you'll need to remove any previously installed versions. Here are some ways you can use to uninstall them: Manually—this involves manually removing any references of Node and npm from your system. Unfortunately, this process is difficult since there may be several directories with Node resources. For example, you may need to delete the node executable and node_modules from /usr/local/lib, delete .npm from the home directory, and delete many other directories. Using a script—this involves running a script to uninstall Node.js and npm automatically from your macOS system. You can find a simple script to use here. Using Homebrew—this package management utility lets you complete the uninstallation process fast and easily. You can run the following command: Then, once your system is clean, you can use any of the following methods to reinstall Node.js and npm on macOS: Reinstalling using a Node installer Reinstalling using Homebrew Reinstalling using a Node version manager Let's talk about each of them. a) Reinstalling using a Node installer To use the official Node installer for reinstalling the tools, go to the Node.js download page and select the version you want to install—just as we described previously. Remember to choose the macOS installer option. If you run the installer, it will complete the reinstallation process for you automatically. b) Reinstalling using Homebrew To reinstall using Homebrew, just run the following command on the macOS terminal: c) Reinstalling using a Node version manager You can also reinstall the two tools using the nvm Node version manager. Since the process for using nvm is the same for both macOS and Linux, we'll describe how to use it in the next section. How to reinstall npm and Node.js on Linux Just like in the previous cases, you'll need to remove any installed version of Node.js and npm before reinstalling them on a Linux distribution, such as Ubuntu. Here are some ways you can use to uninstall them: Using the apt package manager—you can remove Node.js by running the following command: The above command will delete the distro-stable version while retaining the configuration files for later use. However, if you intend to remove the package as well as its configuration files, run the following: Finally, you can delete any unused packages that were installed automatically with the deleted package: Using nvm—you can also use the nvm Node version manager to uninstall Node.js from your system. We'll illustrate how to do this in the next section. Then, once your machine is clean, you can use any of the following methods to reinstall Node.js and npm on Linux: Reinstalling using a Node version manager Reinstalling using the apt package manager Let's talk about each of them. a) Reinstalling using a Node version manager As earlier mentioned, you can use the nvm Node version manager to reinstall Node.js and npm on both macOS and Linux. To install the script-based tool, you can use either Wget or cURL. If using Wget, execute the following on the terminal: If using cURL, execute this: The above commands will install nvm version 0.35.0 on your system. Remember to check the latest version and refer to it accordingly on the command you want to run. To verify if it was installed successfully, run the following: If all went well, it would output nvm. After installing nvm, you can use it to reinstall Node.js on your system. Simply, execute the following command: To reinstall a specific Node.js version, run: For example, to reinstall Node.js version 12.18.0, execute: Once reinstallation is complete, you can set that Node.js version for use as the system-wide default version: Furthermore, you can check the list of Node.js versions available for download by executing the following: To remove a Node.js version that you've set up using nvm, start by establishing if the version is currently active on your system: If it is not actively running, execute the following to uninstall it: On the other hand, if the version targeted for removal is the current active version, you'll need to deactivate nvm first: Then, you can use the above uninstall command to remove it from your system. b) Reinstalling using the apt package manager A simpler way to reinstall Node.js and npm on a Linux distribution, such as Ubuntu, is to use the apt package manager. To do so, you can start by refreshing your local package index: Then, reinstall the distro-stable Node.js version from the repositories: In most cases, this is all you need to get up and running with Node.js. Also, you may want to reinstall npm by running the following command: Conclusion That's how to reinstall npm and Node.js on Windows, macOS, and Linux. After completing the reinstallation, you'll avoid any performance issues that often arise from using malfunctioned versions of the technologies.------ Node.js is a popular open-source, cross-platform server-side environment for building robust applications. Since a vibrant community of contributors backs it, the platform is continuously updated to introduce new features, security patches, and other performance improvements. node –version node -v wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash command -v nvm nvm install node nvm install –lts nvm install <version-number> nvm install 12.18.3 nvm use 12.18.3 nvm lsnvm ls-remotenpm install -g nn <version-number>n 12.18.3 nn ltsn latestnvm install <version-number>nvm install 12.18.3nvm use 12.18.3nvm install latestnvm listnvm list availablewget https://nodejs.org/dist/v12.18.3/node-v12.18.3-linux-x64.tar.xzsudo apt-get install xz-utilstar -C /usr/local -strip-components 1 -xJf node-v12.18.3-linux-x64.tar.xzbrew install nodebrew update #ensure Homebrew is up to date firstbrew upgrade nodebrew switch node 12.18.3 So, updating to the latest Node.js version can help you to make the most of the technology. You can decide to work with the Long-term Supported (LTS) version or the Current version that comes with the latest features. Typically, LTS is recommended for most users because it is a stable version that provides predictable update releases as well as a slower introduction of substantial changes. In this article, you will learn how to quickly and easily update Node.js on different operating systems—macOS, Linux, and Windows. As we'll demonstrate, there are many ways of updating to the next version of Node.js. So, you can choose the option that best meets your system requirements and preferences. These are the updating options we'll talk about: Updating using a Node version manager on macOS or Linux Updating using a Node version manager on Windows Updating using a Node installer on Linux Updating using a Node installer on macOS and Windows Updating using Homebrew on macOS Checking your version of Node.js Before getting started, you can check the version of Node.js currently deployed on your system by running the following command on the terminal: or (shortened method): Let's now talk about the different ways on how to update Node.js. 1. Updating using a Node version manager on macOS or Linux A Node version manager is a utility that lets you install different Node.js versions and switch flawlessly between them on your machine. You can also use it to update your version of Node.js. On macOS or Linux, you can use either of the following Node version managers: nvm n Let's talk about each of them. a) nvm nvm is a script-based version manager for Node.js. To install it on macOS or Linux, you can use either Wget or cURL. For Wget, run the following command on the terminal: For cURL, run the following: The above commands assume that you're installing nvm version 0.35.3. So, you'll need to check the latest version before installing it on your machine. With these commands, you can clone the repository to ~/.nvm. This way, you can make changes to your bash profile, allowing you to access nvm system-wide. To confirm if the installation was successful, you can run the following command: If everything went well, it'd output nvm. Next, you can simply download and update to the latest Node.js version by running the following: Note that node refers to an alias of the latest Node.js version. You can also reference LTS versions in aliases as well as .nvmrc files using the notation lts/* for the most recent LTS releases. Here is an example: If you want to install and upgrade to a specific version, you can run the following: For example, if you want to update Node.js to version 12.18.3, you can run: After the upgrade, you can set that version to be the default version to use throughout your system: You can see the list of installed Node.js versions by running this command: Also, you can see the list of versions available for installation by running this command: b) n n is another useful Node version manager you can use for updating Node.js on macOS and Linux. Since it's an npm-based package, if you already have Node.js available on your environment, you can simply install it by running this command: Then, to download and update to your desired Node.js version, execute the following: For example, if you want to update Node.js to version 12.18.3, you can run: To see a list of your downloaded Node.js versions, run n on its own: You can specify to update to the newest LTS version by running: You can also specify to update to the latest current version by running: You can specify to update to the newest LTS version by running: 2. Updating using a Node version manager on Windows On Windows, you can use the following Node version manager: nvm-windows Let's talk about it. a) nvm-windows nvm-windows is a Node version management tool for the Windows operating system. While it's not the same as nvm, both tools share several usage similarities for Node.js version management. Before installing nvm-windows, it's recommended to uninstall any available Node.js versions from your machine. This will avoid potential conflict issues during installation. Next, you can download and run the latest nvm-setup.zip installer. Also, since the utility runs in an Admin shell, you'll need to begin the Command Prompt or Powershell as an Administrator before using it. If you want to install and upgrade to a specific version, you can run the following: You can specify to update to the newest LTS version by running: For example, if you want to update Node.js to version 12.18.3, you can run: After the upgrade, you can switch to that version: You can also specify to update to the latest stable Node.js version: You can see the list of installed Node.js versions by running this command: Also, you can see the list of versions available for download by running this command: 3. Updating using a Node installer on Linux Using a Node installer is the least recommended way of upgrading Node.js on Linux. Nonetheless, if it's the only route you can use, then follow the following steps: Go to the official Node.js downloads site, which has different Linux binary packages, and select your preferred built-in installer or source code. You can choose either the LTS releases or the latest current releases. Download the binary package using your browser. Or, you can download it using the following Wget command on the terminal: Download the binary package using your browser. Or, you can download it using the following Wget command on the terminal: Remember to change the version number on the Wget command depending on the one you want. Install the xz-utils utility using the following command: This utility will be used for unpacking the binary package. Finally, run the following command to unpack and install the binary package on usr/local: 4. Updating using a Node installer on macOS and Windows Another way of updating your Node.js on macOS and Windows is to go to the official download site and install the most recent version. This way, it'll overwrite your existing old version with the latest one. You can follow the following steps to update it using this method: On the Node.js download page, select either the LTS version or the latest current version. Depending on your system, click either the Windows Installer option or the macOS installer option. Run the installation wizard. It will magically complete the installation process and upgrade your Node.js version by replacing it with the new, updated one. 5. Updating using Homebrew on macOS Homebrew is a popular package management utility for macOS. To use it for installing Node.js, run the following command on your macOS terminal: Later, if you'd like to update it, run the following commands: Furthermore, you can switch between installed Node.js versions:
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Google Cloud The gcloud command-line tool cheat sheet The gcloud cheat sheet A roster of go-to gcloud commands for the gcloud tool, Google Cloud's primary command-line tool.(Also included: introductory primer, understanding commands, and a printable PDF.) Cheat sheet Getting started Get going with the gcloud command-line tool. gcloud init: Initialize, authorize, and configure the gcloud tool. gcloud version: Display version and installed components. gcloud components install: Install specific components. gcloud components update: Update your Cloud SDK to the latest version. gcloud config set project: Set a default Google Cloud project to work on. gcloud info: Display current gcloud tool environment details. Help Cloud SDK is happy to help. gcloud help: Search the gcloud tool reference documents for specific terms. gcloud feedback: Provide feedback for the Cloud SDK team. gcloud topic: Supplementary help material for non-command topics like accessibility, filtering, and formatting. Personalization Make the Cloud SDK your own; personalize your configuration with properties. gcloud config set: Define a property (like compute/zone) for the current configuration. gcloud config get-value: Fetch value of a Cloud SDK property. gcloud config list: Display all the properties for the current configuration. gcloud config configurations create: Create a new named configuration. gcloud config configurations list: Display a list of all available configurations. gcloud config configurations activate: Switch to an existing named configuration. Credentials Grant and revoke authorization to Cloud SDK gcloud auth login: Authorize Google Cloud access for the gcloud tool with Google user credentials and set current account as active. gcloud auth activate-service-account: Like gcloud auth login but with service account credentials. gcloud auth list: List all credentialed accounts. gcloud auth print-access-token: Display the current account's access token. gcloud auth revoke: Remove access credentials for an account. Projects Manage project access policies gcloud projects describe: Display metadata for a project (including its ID). gcloud projects add-iam-policy-binding: Add an IAM policy binding to a specified project. Identity & Access Management Configuring Cloud Identity & Access Management (IAM) preferences and service accounts gcloud iam list-grantable-roles: List IAM grantable roles for a resource. gcloud iam roles create: Create a custom role for a project or org. gcloud iam service-accounts create: Create a service account for a project. gcloud iam service-accounts add-iam-policy-binding: Add an IAM policy binding to a service account. gcloud iam service-accounts set-iam-policy-binding: Replace existing IAM policy binding. gcloud iam service-accounts keys list: List a service account's keys. Docker & Google Kubernetes Engine (GKE) Manage containerized applications on Kubernetes gcloud auth configure-docker: Register the gcloud tool as a Docker credential helper. gcloud container clusters create: Create a cluster to run GKE containers. gcloud container clusters list: List clusters for running GKE containers. gcloud container clusters get-credentials: Update kubeconfig to get kubectl to use a GKE cluster. gcloud container images list-tags: List tag and digest metadata for a container image. Virtual Machines & Compute Engine Create, run, and manage VMs on Google infrastructure gcloud compute zones list: List Compute Engine zones. gcloud compute instances describe: Display a VM instance's details. gcloud compute instances list: List all VM instances in a project. gcloud compute disks snapshot: Create snapshot of persistent disks. gcloud compute snapshots describe: Display a snapshot's details. gcloud compute snapshots delete: Delete a snapshot. gcloud compute ssh: Connect to a VM instance by using SSH. Serverless & App Engine Build highly scalable applications on a fully managed serverless platform gcloud app deploy: Deploy your app's code and configuration to the App Engine server. gcloud app versions list: List all versions of all services deployed to the App Engine server. gcloud app browse: Open the current app in a web browser. gcloud app create: Create an App Engine app within your current project. gcloud app logs read: Display the latest App Engine app logs. Miscellaneous Commands that might come in handy gcloud kms decrypt: Decrypt ciphertext (to a plaintext file) using a Cloud Key Management Service (Cloud KMS) key. gcloud logging logs list: List your project's logs. gcloud sql backups describe: Display info about a Cloud SQL instance backup. gcloud sql export sql: Export data from a Cloud SQL instance to a SQL file. Introductory primer A quick primer for getting started with the gcloud command-line tool. Installing the Cloud SDK Install the Cloud SDK with these installation instructions. Flags, arguments, and other wondrous additions Arguments can be Positional args or Flags Positional args: Set after command name; must respect order of positional args. Flags: Set after positional args; order of flags doesn't matter. A flag can be either a: Name-value pair (--foo=bar), or Boolean (--force/no-force). Additionally, flags can either be: Required Optional: in which case, the default value is used, if the flag is not defined Global flags Some flags are available throughout the gcloud command-line tool experience, like:--help: For when in doubt; display detailed help for a command.--project: If using a project other than the current one.--quiet: Disabling interactive prompting (and applying default values for inputs).--verbosity: Can set verbosity levels at debug, info, warning, error, critical, and none.--version: Display gcloud version information.--format: Set output format as config, csv, default, diff, disable, flattened, get, json, list, multi, none, object, table, text, value, or yaml. Cleaning up results Extricate the most from your output with the filter, format, limit, and sort-by flags. For Compute Engine instances with prefix us and not machine type f1-micro: For a list of projects created on or after 15 January 2018, sorted from oldest to newest, presented as a table with project number, project id and creation time columns with dates and times in local timezone: For a list of ten Compute Engine instances with a label my-label (of any value): Understanding commands The underlying patterns for gcloud commands; to aid self-discovery of commands. Finding gcloud commands The gcloud command-line tool is a tree; non-leaf nodes are command groups and leaf nodes are commands. (Also, tab completion works for commands and resources!) Most gcloud commands follow the following format: For example: gcloud + compute + instances + create + example-instance-1 + --zone=us-central1-a Release level Release Level refers to the command's release status. Example: alpha for alpha commands, beta for beta commands, no release level needed for GA commands. Component Component refers to the different Google Cloud services. Example: compute for Compute Engine, app for App Engine, etc. Entity Entity refers to the plural form of an element or collection of elements under a component. Example: disks, firewalls, images, instances, regions, zones for compute Operation Operation refers to the imperative verb form of the operation to be performed on the entity. Example: Common operations are describe, list, create/update, delete/clear, import, export, copy, remove, add, reset, restart, restore, run, and deploy. Positional args Positional args refer to the required, order-specific arguments needed to execute the command. Example: <INSTANCE_NAMES> is the required positional argument for gcloud compute instances create. Flags Flags refer to the additional arguments, --flag-name(=value), passed in to the command after positional args. Example: --machine-type=<MACHINE_TYPE> and --preemptible are optional flags for gcloud compute instances create.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Github Search Search The GitHub Search API lets you to search for the specific item efficiently. The GitHub Search API lets you to search for the specific item efficiently. The Search API helps you search for the specific item you want to find. For example, you can find a user or a specific file in a repository. Think of it the way you think of performing a search on Google. It's designed to help you find the one result you're looking for (or maybe the few results you're looking for). Just like searching on Google, you sometimes want to see a few pages of search results so that you can find the item that best meets your needs. To satisfy that need, the GitHub Search API provides up to 1,000 results for each search. You can narrow your search using queries. To learn more about the search query syntax, see " Constructing a search query." Ranking search results Unless another sort option is provided as a query parameter, results are sorted by best match in descending order. Multiple factors are combined to boost the most relevant item to the top of the result list. Rate limit The Search API has a custom rate limit. For requests using Basic Authentication, OAuth, or client ID and secret, you can make up to 30 requests per minute. For unauthenticated requests, the rate limit allows you to make up to 10 requests per minute. See the rate limit documentation for details on determining your current rate limit status. Constructing a search query Each endpoint in the Search API uses query parameters to perform searches on GitHub. See the individual endpoint in the Search API for an example that includes the endpoint and query parameters. A query can contain any combination of search qualifiers supported on GitHub. The format of the search query is: SEARCH_KEYWORD_1 SEARCH_KEYWORD_N QUALIFIER_1 QUALIFIER_N For example, if you wanted to search for all repositories owned by defunkt that contained the word GitHub and Octocat in the README file, you would use the following query with the search repositories endpoint: GitHub Octocat in:readme user:defunkt Note: Be sure to use your language's preferred HTML-encoder to construct your query strings. For example: const queryString = 'q=' + encodeURIComponent('GitHub Octocat in:readme user:defunkt'); See " Searching on GitHub" for a complete list of available qualifiers, their format, and an example of how to use them. For information about how to use operators to match specific quantities, dates, or to exclude results, see " Understanding the search syntax." Limitations on query length The Search API does not support queries that: are longer than 256 characters (not including operators or qualifiers). have more than five AND, OR, or NOT operators. These search queries will return a "Validation failed" error message. Timeouts and incomplete results To keep the Search API fast for everyone, we limit how long any individual query can run. For queries that exceed the time limit, the API returns the matches that were already found prior to the timeout, and the response has the incomplete_results property set to true. Reaching a timeout does not necessarily mean that search results are incomplete. More results might have been found, but also might not. Access errors or missing search results You need to successfully authenticate and have access to the repositories in your search queries, otherwise, you'll see a 422 Unprocessible Entry error with a "Validation Failed" message. For example, your search will fail if your query includes repo:, user:, or org: qualifiers that request resources that you don't have access to when you sign in on GitHub. When your search query requests multiple resources, the response will only contain the resources that you have access to and will not provide an error message listing the resources that were not returned. For example, if your search query searches for the octocat/test and codertocat/test repositories, but you only have access to octocat/test, your response will show search results for octocat/test and nothing for codertocat/test. This behavior mimics how search works on GitHub. Search code Searches for query terms inside of a file. This method returns up to 100 results per page. When searching for code, you can get text match metadata for the file content and file path fields when you pass the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to find the definition of the addClass function inside jQuery repository, your query would look something like this: q=addClass+in:file+language:js+repo:jquery/jquery This query searches for the keyword addClass within a file's contents. The query limits the search to files where the language is JavaScript in the jquery/jquery repository. Considerations for code search Due to the complexity of searching code, there are a few restrictions on how searches are performed: Only the default branch is considered. In most cases, this will be the master branch. Only files smaller than 384 KB are searchable. You must always include at least one search term when searching source code. For example, searching for language:go is not valid, while amazing language:go is. get /search/code Parameters Name Type In Description accept string header Setting to application/vnd.github.v3+json is recommended.| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query. See " Searching code" for a detailed list of qualifiers.| | sort | string | query | Sorts the results of your query. Can only be indexed, which indicates how recently a file has been indexed by the GitHub search infrastructure. Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/search/code JavaScript (@octokit/core.js) await octokit.request('GET /search/code', { q: 'q' }) Response Status: 200 OK { "total_count": 7, "incomplete_results": false, "items": [ { "name": "classes.js", "path": "src/attributes/classes.js", "sha": "d7212f9dee2dcc18f084d7df8f417b80846ded5a", "url": "https://api.github.com/repositories/167174/contents/src/attributes/classes.js?ref=825ac3773694e0cd23ee74895fd5aeb535b27da4", "git_url": "https://api.github.com/repositories/167174/git/blobs/d7212f9dee2dcc18f084d7df8f417b80846ded5a", "html_url": "https://github.com/jquery/jquery/blob/825ac3773694e0cd23ee74895fd5aeb535b27da4/src/attributes/classes.js", "repository": { "id": 167174, "node_id": "MDEwOlJlcG9zaXRvcnkxNjcxNzQ=", "name": "jquery", "full_name": "jquery/jquery", "owner": { "login": "jquery", "id": 70142, "node_id": "MDQ6VXNlcjcwMTQy", "avatar_url": "https://0.gravatar.com/avatar/6906f317a4733f4379b06c32229ef02f?d=https%3A%2F%2Fidenticons.github.com%2Ff426f04f2f9813718fb806b30e0093de.png", "gravatar_id": "", "url": "https://api.github.com/users/jquery", "html_url": "https://github.com/jquery", "followers_url": "https://api.github.com/users/jquery/followers", "following_url": "https://api.github.com/users/jquery/following{/other_user}", "gists_url": "https://api.github.com/users/jquery/gists{/gist_id}", "starred_url": "https://api.github.com/users/jquery/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/jquery/subscriptions", "organizations_url": "https://api.github.com/users/jquery/orgs", "repos_url": "https://api.github.com/users/jquery/repos", "events_url": "https://api.github.com/users/jquery/events{/privacy}", "received_events_url": "https://api.github.com/users/jquery/received_events", "type": "Organization", "site_admin": false }, "private": false, "html_url": "https://github.com/jquery/jquery", "description": "jQuery JavaScript Library", "fork": false, "url": "https://api.github.com/repos/jquery/jquery", "forks_url": "https://api.github.com/repos/jquery/jquery/forks", "keys_url": "https://api.github.com/repos/jquery/jquery/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/jquery/jquery/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/jquery/jquery/teams", "hooks_url": "https://api.github.com/repos/jquery/jquery/hooks", "issue_events_url": "https://api.github.com/repos/jquery/jquery/issues/events{/number}", "events_url": "https://api.github.com/repos/jquery/jquery/events", "assignees_url": "https://api.github.com/repos/jquery/jquery/assignees{/user}", "branches_url": "https://api.github.com/repos/jquery/jquery/branches{/branch}", "tags_url": "https://api.github.com/repos/jquery/jquery/tags", "blobs_url": "https://api.github.com/repos/jquery/jquery/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/jquery/jquery/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/jquery/jquery/git/refs{/sha}", "trees_url": "https://api.github.com/repos/jquery/jquery/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/jquery/jquery/statuses/{sha}", "languages_url": "https://api.github.com/repos/jquery/jquery/languages", "stargazers_url": "https://api.github.com/repos/jquery/jquery/stargazers", "contributors_url": "https://api.github.com/repos/jquery/jquery/contributors", "subscribers_url": "https://api.github.com/repos/jquery/jquery/subscribers", "subscription_url": "https://api.github.com/repos/jquery/jquery/subscription", "commits_url": "https://api.github.com/repos/jquery/jquery/commits{/sha}", "git_commits_url": "https://api.github.com/repos/jquery/jquery/git/commits{/sha}", "comments_url": "https://api.github.com/repos/jquery/jquery/comments{/number}", "issue_comment_url": "https://api.github.com/repos/jquery/jquery/issues/comments/{number}", "contents_url": "https://api.github.com/repos/jquery/jquery/contents/{+path}", "compare_url": "https://api.github.com/repos/jquery/jquery/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/jquery/jquery/merges", "archive_url": "https://api.github.com/repos/jquery/jquery/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/jquery/jquery/downloads", "issues_url": "https://api.github.com/repos/jquery/jquery/issues{/number}", "pulls_url": "https://api.github.com/repos/jquery/jquery/pulls{/number}", "milestones_url": "https://api.github.com/repos/jquery/jquery/milestones{/number}", "notifications_url": "https://api.github.com/repos/jquery/jquery/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/jquery/jquery/labels{/name}", "deployments_url": "http://api.github.com/repos/octocat/Hello-World/deployments", "releases_url": "http://api.github.com/repos/octocat/Hello-World/releases{/id}" }, "score": 1 } ] } Not modified Status: 304 Not Modified Forbidden Status: 403 Forbidden Validation failed Status: 422 Unprocessable Entity Service unavailable Status: 503 Service Unavailable Notes Works with GitHub Apps Search commits Find commits via various criteria on the default branch (usually master). This method returns up to 100 results per page. When searching for commits, you can get text match metadata for the message field when you provide the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to find commits related to CSS in the octocat/Spoon-Knife repository. Your query would look something like this: q=repo:octocat/Spoon-Knife+css get /search/commits Parameters Name Type In Description accept string header This API is under preview and subject to change. See preview notice| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query. See " Searching commits" for a detailed list of qualifiers.| | sort | string | query | Sorts the results of your query by author-date or committer-date. Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.cloak-preview+json" \ https://api.github.com/search/commits JavaScript (@octokit/core.js) await octokit.request('GET /search/commits', { q: 'q', mediaType: { previews: [ 'cloak' ] } }) Response Status: 200 OK { "total_count": 1, "incomplete_results": false, "items": [ { "url": "https://api.github.com/repos/octocat/Spoon-Knife/commits/bb4cc8d3b2e14b3af5df699876dd4ff3acd00b7f", "sha": "bb4cc8d3b2e14b3af5df699876dd4ff3acd00b7f", "html_url": "https://github.com/octocat/Spoon-Knife/commit/bb4cc8d3b2e14b3af5df699876dd4ff3acd00b7f", "comments_url": "https://api.github.com/repos/octocat/Spoon-Knife/commits/bb4cc8d3b2e14b3af5df699876dd4ff3acd00b7f/comments", "commit": { "url": "https://api.github.com/repos/octocat/Spoon-Knife/git/commits/bb4cc8d3b2e14b3af5df699876dd4ff3acd00b7f", "author": { "date": "2014-02-04T14:38:36-08:00", "name": "The Octocat", "email": "octocat@nowhere.com" }, "committer": { "date": "2014-02-12T15:18:55-08:00", "name": "The Octocat", "email": "octocat@nowhere.com" }, "message": "Create styles.css and updated README", "tree": { "url": "https://api.github.com/repos/octocat/Spoon-Knife/git/trees/a639e96f9038797fba6e0469f94a4b0cc459fa68", "sha": "a639e96f9038797fba6e0469f94a4b0cc459fa68" }, "comment_count": 8 }, "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=3", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "committer": {}, "parents": [ { "url": "https://api.github.com/repos/octocat/Spoon-Knife/commits/a30c19e3f13765a3b48829788bc1cb8b4e95cee4", "html_url": "https://github.com/octocat/Spoon-Knife/commit/a30c19e3f13765a3b48829788bc1cb8b4e95cee4", "sha": "a30c19e3f13765a3b48829788bc1cb8b4e95cee4" } ], "repository": { "id": 1300192, "node_id": "MDEwOlJlcG9zaXRvcnkxMzAwMTky", "name": "Spoon-Knife", "full_name": "octocat/Spoon-Knife", "owner": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=3", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/octocat/Spoon-Knife", "description": "This repo is for demonstration purposes only.", "fork": false, "url": "https://api.github.com/repos/octocat/Spoon-Knife", "forks_url": "https://api.github.com/repos/octocat/Spoon-Knife/forks", "keys_url": "https://api.github.com/repos/octocat/Spoon-Knife/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/octocat/Spoon-Knife/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/octocat/Spoon-Knife/teams", "hooks_url": "https://api.github.com/repos/octocat/Spoon-Knife/hooks", "issue_events_url": "https://api.github.com/repos/octocat/Spoon-Knife/issues/events{/number}", "events_url": "https://api.github.com/repos/octocat/Spoon-Knife/events", "assignees_url": "https://api.github.com/repos/octocat/Spoon-Knife/assignees{/user}", "branches_url": "https://api.github.com/repos/octocat/Spoon-Knife/branches{/branch}", "tags_url": "https://api.github.com/repos/octocat/Spoon-Knife/tags", "blobs_url": "https://api.github.com/repos/octocat/Spoon-Knife/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/octocat/Spoon-Knife/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/octocat/Spoon-Knife/git/refs{/sha}", "trees_url": "https://api.github.com/repos/octocat/Spoon-Knife/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/octocat/Spoon-Knife/statuses/{sha}", "languages_url": "https://api.github.com/repos/octocat/Spoon-Knife/languages", "stargazers_url": "https://api.github.com/repos/octocat/Spoon-Knife/stargazers", "contributors_url": "https://api.github.com/repos/octocat/Spoon-Knife/contributors", "subscribers_url": "https://api.github.com/repos/octocat/Spoon-Knife/subscribers", "subscription_url": "https://api.github.com/repos/octocat/Spoon-Knife/subscription", "commits_url": "https://api.github.com/repos/octocat/Spoon-Knife/commits{/sha}", "git_commits_url": "https://api.github.com/repos/octocat/Spoon-Knife/git/commits{/sha}", "comments_url": "https://api.github.com/repos/octocat/Spoon-Knife/comments{/number}", "issue_comment_url": "https://api.github.com/repos/octocat/Spoon-Knife/issues/comments{/number}", "contents_url": "https://api.github.com/repos/octocat/Spoon-Knife/contents/{+path}", "compare_url": "https://api.github.com/repos/octocat/Spoon-Knife/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/octocat/Spoon-Knife/merges", "archive_url": "https://api.github.com/repos/octocat/Spoon-Knife/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/octocat/Spoon-Knife/downloads", "issues_url": "https://api.github.com/repos/octocat/Spoon-Knife/issues{/number}", "pulls_url": "https://api.github.com/repos/octocat/Spoon-Knife/pulls{/number}", "milestones_url": "https://api.github.com/repos/octocat/Spoon-Knife/milestones{/number}", "notifications_url": "https://api.github.com/repos/octocat/Spoon-Knife/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/octocat/Spoon-Knife/labels{/name}", "releases_url": "https://api.github.com/repos/octocat/Spoon-Knife/releases{/id}", "deployments_url": "https://api.github.com/repos/octocat/Spoon-Knife/deployments" }, "score": 1, "node_id": "MDQ6VXNlcjU4MzIzMQ==" } ] } Not modified Status: 304 Not Modified Preview header missing Status: 415 Unsupported Media Type Notes Works with GitHub Apps Preview notice The Commit Search API is currently available for developers to preview. During the preview period, the APIs may change without advance notice. Please see the blog post for full details. To access the API you must provide a custom media type in the Accept header: application/vnd.github.cloak-preview ☝️This header is required. Search issues and pull requests Find issues by state and keyword. This method returns up to 100 results per page. When searching for issues, you can get text match metadata for the issue title, issue body, and issue comment body fields when you pass the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to find the oldest unresolved Python bugs on Windows. Your query might look something like this. q=windows+label:bug+language:python+state:open&sort=created&order=asc This query searches for the keyword windows, within any open issue that is labeled as bug. The search runs across repositories whose primary language is Python. The results are sorted by creation date in ascending order, which means the oldest issues appear first in the search results. Note: For user-to-server GitHub App requests, you can't retrieve a combination of issues and pull requests in a single query. Requests that don't include the is:issue or is:pull-request qualifier will receive an HTTP 422 Unprocessable Entity response. To get results for both issues and pull requests, you must send separate queries for issues and pull requests. For more information about the is qualifier, see " Searching only issues or pull requests." get /search/issues Parameters Name Type In Description accept string header Setting to application/vnd.github.v3+json is recommended.| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query. See " Searching issues and pull requests" for a detailed list of qualifiers.| | sort | string | query | Sorts the results of your query by the number of comments, reactions, reactions-+1, reactions--1, reactions-smile, reactions-thinking_face, reactions-heart, reactions-tada, or interactions. You can also sort results by how recently the items were created or updated, Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/search/issues JavaScript (@octokit/core.js) await octokit.request('GET /search/issues', { q: 'q' }) Response Status: 200 OK { "total_count": 280, "incomplete_results": false, "items": [ { "url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/issues/132", "repository_url": "https://api.github.com/repos/batterseapower/pinyin-toolkit", "labels_url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/issues/132/labels{/name}", "comments_url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/issues/132/comments", "events_url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/issues/132/events", "html_url": "https://github.com/batterseapower/pinyin-toolkit/issues/132", "id": 35802, "node_id": "MDU6SXNzdWUzNTgwMg==", "number": 132, "title": "Line Number Indexes Beyond 20 Not Displayed", "user": { "login": "Nick3C", "id": 90254, "node_id": "MDQ6VXNlcjkwMjU0", "avatar_url": "https://secure.gravatar.com/avatar/934442aadfe3b2f4630510de416c5718?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png", "gravatar_id": "", "url": "https://api.github.com/users/Nick3C", "html_url": "https://github.com/Nick3C", "followers_url": "https://api.github.com/users/Nick3C/followers", "following_url": "https://api.github.com/users/Nick3C/following{/other_user}", "gists_url": "https://api.github.com/users/Nick3C/gists{/gist_id}", "starred_url": "https://api.github.com/users/Nick3C/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/Nick3C/subscriptions", "organizations_url": "https://api.github.com/users/Nick3C/orgs", "repos_url": "https://api.github.com/users/Nick3C/repos", "events_url": "https://api.github.com/users/Nick3C/events{/privacy}", "received_events_url": "https://api.github.com/users/Nick3C/received_events", "type": "User", "site_admin": true }, "labels": [ { "id": 4, "node_id": "MDU6TGFiZWw0", "url": "https://api.github.com/repos/batterseapower/pinyin-toolkit/labels/bug", "name": "bug", "color": "ff0000" } ], "state": "open", "assignee": null, "milestone": { "url": "https://api.github.com/repos/octocat/Hello-World/milestones/1", "html_url": "https://github.com/octocat/Hello-World/milestones/v1.0", "labels_url": "https://api.github.com/repos/octocat/Hello-World/milestones/1/labels", "id": 1002604, "node_id": "MDk6TWlsZXN0b25lMTAwMjYwNA==", "number": 1, "state": "open", "title": "v1.0", "description": "Tracking milestone for version 1.0", "creator": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "received_events_url": "https://api.github.com/users/octocat/received_events", "type": "User", "site_admin": false }, "open_issues": 4, "closed_issues": 8, "created_at": "2011-04-10T20:09:31Z", "updated_at": "2014-03-03T18:58:10Z", "closed_at": "2013-02-12T13:22:01Z", "due_on": "2012-10-09T23:39:01Z" }, "comments": 15, "created_at": "2009-07-12T20:10:41Z", "updated_at": "2009-07-19T09:23:43Z", "closed_at": null, "pull_request": { "url": "https://api/github.com/repos/octocat/Hello-World/pull/1347", "html_url": "https://github.com/octocat/Hello-World/pull/1347", "diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff", "patch_url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347" }, "body": "...", "score": 1, "locked": true, "author_association": "COLLABORATOR" } ] } Not modified Status: 304 Not Modified Forbidden Status: 403 Forbidden Validation failed Status: 422 Unprocessable Entity Service unavailable Status: 503 Service Unavailable Notes Works with GitHub Apps Search labels Find labels in a repository with names or descriptions that match search keywords. Returns up to 100 results per page. When searching for labels, you can get text match metadata for the label name and description fields when you pass the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to find labels in the linguist repository that match bug, defect, or enhancement. Your query might look like this: q=bug+defect+enhancement&repository_id=64778136 The labels that best match the query appear first in the search results. get /search/labels Parameters Name Type In Description accept string header Setting to application/vnd.github.v3+json is recommended.| | repository_id | integer | query | The id of the repository.| | q | string | query | The search keywords. This endpoint does not accept qualifiers in the query. To learn more about the format of the query, see Constructing a search query.| | sort | string | query | Sorts the results of your query by when the label was created or updated. Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/search/labels JavaScript (@octokit/core.js) await octokit.request('GET /search/labels', { repository_id: 42, q: 'q' }) Response Status: 200 OK { "total_count": 2, "incomplete_results": false, "items": [ { "id": 418327088, "node_id": "MDU6TGFiZWw0MTgzMjcwODg=", "url": "https://api.github.com/repos/octocat/linguist/labels/enhancement", "name": "enhancement", "color": "84b6eb", "default": true, "description": "New feature or request.", "score": 1 }, { "id": 418327086, "node_id": "MDU6TGFiZWw0MTgzMjcwODY=", "url": "https://api.github.com/repos/octocat/linguist/labels/bug", "name": "bug", "color": "ee0701", "default": true, "description": "Something isn't working.", "score": 1 } ] } Not modified Status: 304 Not Modified Forbidden Status: 403 Forbidden Resource not found Status: 404 Not Found Validation failed Status: 422 Unprocessable Entity Notes Works with GitHub Apps Search repositories Find repositories via various criteria. This method returns up to 100 results per page. When searching for repositories, you can get text match metadata for the name and description fields when you pass the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to search for popular Tetris repositories written in assembly code, your query might look like this: q=tetris+language:assembly&sort=stars&order=desc This query searches for repositories with the word tetris in the name, the description, or the README. The results are limited to repositories where the primary language is assembly. The results are sorted by stars in descending order, so that the most popular repositories appear first in the search results. When you include the mercy preview header, you can also search for multiple topics by adding more topic: instances. For example, your query might look like this: q=topic:ruby+topic:rails get /search/repositories Parameters Name Type In Description accept string header Setting to application/vnd.github.v3+json is recommended. See preview notice| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query. See " Searching for repositories" for a detailed list of qualifiers.| | sort | string | query | Sorts the results of your query by number of stars, forks, or help-wanted-issues or how recently the items were updated. Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/search/repositories JavaScript (@octokit/core.js) await octokit.request('GET /search/repositories', { q: 'q' }) Response Status: 200 OK { "total_count": 40, "incomplete_results": false, "items": [ { "id": 3081286, "node_id": "MDEwOlJlcG9zaXRvcnkzMDgxMjg2", "name": "Tetris", "full_name": "dtrupenn/Tetris", "owner": { "login": "dtrupenn", "id": 872147, "node_id": "MDQ6VXNlcjg3MjE0Nw==", "avatar_url": "https://secure.gravatar.com/avatar/e7956084e75f239de85d3a31bc172ace?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png", "gravatar_id": "", "url": "https://api.github.com/users/dtrupenn", "received_events_url": "https://api.github.com/users/dtrupenn/received_events", "type": "User", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/octocat/followers", "following_url": "https://api.github.com/users/octocat/following{/other_user}", "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", "organizations_url": "https://api.github.com/users/octocat/orgs", "repos_url": "https://api.github.com/users/octocat/repos", "events_url": "https://api.github.com/users/octocat/events{/privacy}", "site_admin": true }, "private": false, "html_url": "https://github.com/dtrupenn/Tetris", "description": "A C implementation of Tetris using Pennsim through LC4", "fork": false, "url": "https://api.github.com/repos/dtrupenn/Tetris", "created_at": "2012-01-01T00:31:50Z", "updated_at": "2013-01-05T17:58:47Z", "pushed_at": "2012-01-01T00:37:02Z", "homepage": "https://github.com", "size": 524, "stargazers_count": 1, "watchers_count": 1, "language": "Assembly", "forks_count": 0, "open_issues_count": 0, "master_branch": "master", "default_branch": "master", "score": 1, "archive_url": "https://api.github.com/repos/dtrupenn/Tetris/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/dtrupenn/Tetris/assignees{/user}", "blobs_url": "https://api.github.com/repos/dtrupenn/Tetris/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/dtrupenn/Tetris/branches{/branch}", "collaborators_url": "https://api.github.com/repos/dtrupenn/Tetris/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/dtrupenn/Tetris/comments{/number}", "commits_url": "https://api.github.com/repos/dtrupenn/Tetris/commits{/sha}", "compare_url": "https://api.github.com/repos/dtrupenn/Tetris/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/dtrupenn/Tetris/contents/{+path}", "contributors_url": "https://api.github.com/repos/dtrupenn/Tetris/contributors", "deployments_url": "https://api.github.com/repos/dtrupenn/Tetris/deployments", "downloads_url": "https://api.github.com/repos/dtrupenn/Tetris/downloads", "events_url": "https://api.github.com/repos/dtrupenn/Tetris/events", "forks_url": "https://api.github.com/repos/dtrupenn/Tetris/forks", "git_commits_url": "https://api.github.com/repos/dtrupenn/Tetris/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/dtrupenn/Tetris/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/dtrupenn/Tetris/git/tags{/sha}", "git_url": "git:github.com/dtrupenn/Tetris.git", "issue_comment_url": "https://api.github.com/repos/dtrupenn/Tetris/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/dtrupenn/Tetris/issues/events{/number}", "issues_url": "https://api.github.com/repos/dtrupenn/Tetris/issues{/number}", "keys_url": "https://api.github.com/repos/dtrupenn/Tetris/keys{/key_id}", "labels_url": "https://api.github.com/repos/dtrupenn/Tetris/labels{/name}", "languages_url": "https://api.github.com/repos/dtrupenn/Tetris/languages", "merges_url": "https://api.github.com/repos/dtrupenn/Tetris/merges", "milestones_url": "https://api.github.com/repos/dtrupenn/Tetris/milestones{/number}", "notifications_url": "https://api.github.com/repos/dtrupenn/Tetris/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/dtrupenn/Tetris/pulls{/number}", "releases_url": "https://api.github.com/repos/dtrupenn/Tetris/releases{/id}", "ssh_url": "git@github.com:dtrupenn/Tetris.git", "stargazers_url": "https://api.github.com/repos/dtrupenn/Tetris/stargazers", "statuses_url": "https://api.github.com/repos/dtrupenn/Tetris/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/dtrupenn/Tetris/subscribers", "subscription_url": "https://api.github.com/repos/dtrupenn/Tetris/subscription", "tags_url": "https://api.github.com/repos/dtrupenn/Tetris/tags", "teams_url": "https://api.github.com/repos/dtrupenn/Tetris/teams", "trees_url": "https://api.github.com/repos/dtrupenn/Tetris/git/trees{/sha}", "clone_url": "https://github.com/dtrupenn/Tetris.git", "mirror_url": "git:git.example.com/dtrupenn/Tetris", "hooks_url": "https://api.github.com/repos/dtrupenn/Tetris/hooks", "svn_url": "https://svn.github.com/dtrupenn/Tetris", "forks": 1, "open_issues": 1, "watchers": 1, "has_issues": true, "has_projects": true, "has_pages": true, "has_wiki": true, "has_downloads": true, "archived": true, "disabled": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" } } ] } Not modified Status: 304 Not Modified Validation failed Status: 422 Unprocessable Entity Service unavailable Status: 503 Service Unavailable Notes Works with GitHub Apps Preview notice The topics property for repositories on GitHub is currently available for developers to preview. To view the topics property in calls that return repository results, you must provide a custom media type in the Accept header: application/vnd.github.mercy-preview+json Search topics Find topics via various criteria. Results are sorted by best match. This method returns up to 100 results per page. See " Searching topics" for a detailed list of qualifiers. When searching for topics, you can get text match metadata for the topic's short_description, description, name, or display_name field when you pass the text-match media type. For more details about how to receive highlighted search results, see Text match metadata. For example, if you want to search for topics related to Ruby that are featured on https://github.com/topics. Your query might look like this: q=ruby+is:featured This query searches for topics with the keyword ruby and limits the results to find only topics that are featured. The topics that are the best match for the query appear first in the search results. get /search/topics Parameters Name Type In Description accept string header This API is under preview and subject to change. See preview notice| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query.| | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.mercy-preview+json" \ https://api.github.com/search/topics JavaScript (@octokit/core.js) await octokit.request('GET /search/topics', { q: 'q', mediaType: { previews: [ 'mercy' ] } }) Response Status: 200 OK { "total_count": 6, "incomplete_results": false, "items": [ { "name": "ruby", "display_name": "Ruby", "short_description": "Ruby is a scripting language designed for simplified object-oriented programming.", "description": "Ruby was developed by Yukihiro \"Matz\" Matsumoto in 1995 with the intent of having an easily readable programming language. It is integrated with the Rails framework to create dynamic web-applications. Ruby's syntax is similar to that of Perl and Python.", "created_by": "Yukihiro Matsumoto", "released": "December 21, 1995", "created_at": "2016-11-28T22:03:59Z", "updated_at": "2017-10-30T18:16:32Z", "featured": true, "curated": true, "score": 1 }, { "name": "rails", "display_name": "Rails", "short_description": "Ruby on Rails (Rails) is a web application framework written in Ruby.", "description": "Ruby on Rails (Rails) is a web application framework written in Ruby. It is meant to help simplify the building of complex websites.", "created_by": "David Heinemeier Hansson", "released": "December 13 2005", "created_at": "2016-12-09T17:03:50Z", "updated_at": "2017-10-30T16:20:19Z", "featured": true, "curated": true, "score": 1 }, { "name": "python", "display_name": "Python", "short_description": "Python is a dynamically typed programming language.", "description": "Python is a dynamically typed programming language designed by Guido Van Rossum. Much like the programming language Ruby, Python was designed to be easily read by programmers. Because of its large following and many libraries, Python can be implemented and used to do anything from webpages to scientific research.", "created_by": "Guido van Rossum", "released": "February 20, 1991", "created_at": "2016-12-07T00:07:02Z", "updated_at": "2017-10-27T22:45:43Z", "featured": true, "curated": true, "score": 1 }, { "name": "jekyll", "display_name": "Jekyll", "short_description": "Jekyll is a simple, blog-aware static site generator.", "description": "Jekyll is a blog-aware, site generator written in Ruby. It takes raw text files, runs it through a renderer and produces a publishable static website.", "created_by": "Tom Preston-Werner", "released": "2008", "created_at": "2016-12-16T21:53:08Z", "updated_at": "2017-10-27T19:00:24Z", "featured": true, "curated": true, "score": 1 }, { "name": "sass", "display_name": "Sass", "short_description": "Sass is a stable extension to classic CSS.", "description": "Sass is a stylesheet language with a main implementation in Ruby. It is an extension of CSS that makes improvements to the old stylesheet format, such as being able to declare variables and using a cleaner nesting syntax.", "created_by": "Hampton Catlin, Natalie Weizenbaum, Chris Eppstein", "released": "November 28, 2006", "created_at": "2016-12-16T21:53:45Z", "updated_at": "2018-01-16T16:30:40Z", "featured": true, "curated": true, "score": 1 }, { "name": "homebrew", "display_name": "Homebrew", "short_description": "Homebrew is a package manager for macOS.", "description": "Homebrew is a package manager for Apple's macOS operating system. It simplifies the installation of software and is popular in the Ruby on Rails community.", "created_by": "Max Howell", "released": "2009", "created_at": "2016-12-17T20:30:44Z", "updated_at": "2018-02-06T16:14:56Z", "featured": true, "curated": true, "score": 1 } ] } Not modified Status: 304 Not Modified Preview header missing Status: 415 Unsupported Media Type Notes Works with GitHub Apps Preview notice The topics property for repositories on GitHub is currently available for developers to preview. To view the topics property in calls that return repository results, you must provide a custom media type in the Accept header: application/vnd.github.mercy-preview+json ☝️This header is required. Search users Find users via various criteria. This method returns up to 100 results per page. When searching for users, you can get text match metadata for the issue login, email, and name fields when you pass the text-match media type. For more details about highlighting search results, see Text match metadata. For more details about how to receive highlighted search results, see Text match metadata. For example, if you're looking for a list of popular users, you might try this query: q=tom+repos:%3E42+followers:%3E1000 This query searches for users with the name tom. The results are restricted to users with more than 42 repositories and over 1,000 followers. get /search/users Parameters Name Type In Description accept string header Setting to application/vnd.github.v3+json is recommended.| | q | string | query | The query contains one or more search keywords and qualifiers. Qualifiers allow you to limit your search to specific areas of GitHub. The REST API supports the same qualifiers as GitHub.com. To learn more about the format of the query, see Constructing a search query. See " Searching users" for a detailed list of qualifiers.| | sort | string | query | Sorts the results of your query by number of followers or repositories, or when the person joined GitHub. Default: best match| | order | string | query | Determines whether the first search result returned is the highest number of matches ( desc) or lowest number of matches ( asc). This parameter is ignored unless you provide sort. Default: desc | | per_page | integer | query | Results per page (max 100) Default: 30 | | page | integer | query | Page number of the results to fetch. Default: 1 | Code samples Shell curl \ -H "Accept: application/vnd.github.v3+json" \ https://api.github.com/search/users JavaScript (@octokit/core.js) await octokit.request('GET /search/users', { q: 'q' }) Response Status: 200 OK { "total_count": 12, "incomplete_results": false, "items": [ { "login": "mojombo", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://secure.gravatar.com/avatar/25c7c18223fb42a4c6ae1c8db6f50f9b?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png", "gravatar_id": "", "url": "https://api.github.com/users/mojombo", "html_url": "https://github.com/mojombo", "followers_url": "https://api.github.com/users/mojombo/followers", "subscriptions_url": "https://api.github.com/users/mojombo/subscriptions", "organizations_url": "https://api.github.com/users/mojombo/orgs", "repos_url": "https://api.github.com/users/mojombo/repos", "received_events_url": "https://api.github.com/users/mojombo/received_events", "type": "User", "score": 1, "following_url": "https://api.github.com/users/mojombo/following{/other_user}", "gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}", "starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}", "events_url": "https://api.github.com/users/mojombo/events{/privacy}", "site_admin": true } ] } Not modified Status: 304 Not Modified Validation failed Status: 422 Unprocessable Entity Service unavailable Status: 503 Service Unavailable Notes Works with GitHub Apps Text match metadata On GitHub, you can use the context provided by code snippets and highlights in search results. The Search API offers additional metadata that allows you to highlight the matching search terms when displaying search results. Requests can opt to receive those text fragments in the response, and every fragment is accompanied by numeric offsets identifying the exact location of each matching search term. To get this metadata in your search results, specify the text-match media type in your Accept header. application/vnd.github.v3.text-match+json When you provide the text-match media type, you will receive an extra key in the JSON payload called text_matches that provides information about the position of your search terms within the text and the property that includes the search term. Inside the text_matches array, each object includes the following attributes: Name Description object_url The URL for the resource that contains a string property matching one of the search terms. object_type The name for the type of resource that exists at the given object_url. property The name of a property of the resource that exists at object_url. That property is a string that matches one of the search terms. (In the JSON returned from object_url, the full content for the fragment will be found in the property with this name.) fragment A subset of the value of property. This is the text fragment that matches one or more of the search terms. matches An array of one or more search terms that are present in fragment. The indices (i.e., "offsets") are relative to the fragment. (They are not relative to the full content of property.) Example Using cURL, and the example issue search above, our API request would look like this: curl -H 'Accept: application/vnd.github.v3.text-match+json' \ 'https://api.github.com/search/issues?q=windows+label:bug+language:python+state:open&sort=created&order=asc' The response will include a text_matches array for each search result. In the JSON below, we have two objects in the text_matches array. The first text match occurred in the body property of the issue. We see a fragment of text from the issue body. The search term ( windows) appears twice within that fragment, and we have the indices for each occurrence. The second text match occurred in the body property of one of the issue's comments. We have the URL for the issue comment. And of course, we see a fragment of text from the comment body. The search term ( windows) appears once within that fragment.{ "text_matches": [ { "object_url": "https://api.github.com/repositories/215335/issues/132", "object_type": "Issue", "property": "body", "fragment": "comprehensive windows font I know of).\n\nIf we can find a commonly distributed windows font that supports them then no problem (we can use html font tags) but otherwise the '(21)' style is probably better.\n", "matches": [ { "text": "windows", "indices": [ 14, 21 ] }, { "text": "windows", "indices": [ 78, 85 ] } ] }, { "object_url": "https://api.github.com/repositories/215335/issues/comments/25688", "object_type": "IssueComment", "property": "body", "fragment": " right after that are a bit broken IMHO :). I suppose we could have some hack that maxes out at whatever the font does...\n\nI'll check what the state of play is on Windows.\n", "matches": [ { "text": "Windows", "indices": [ 163, 170 ] } ] } ] }
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Web Dev Bookmarks Web Dev Bookmarks Frontend Development Appearance The outward or visible aspect of a website. Animation: The process of creating motion and shape change. Animate.css: Just-add-water CSS animations. Animate.less: A bunch of cool, fun, and cross-browser animations converted into LESS for you to use in your Bootstrap projects. Anime.js: Anime is a flexible yet lightweight JavaScript animation library. It works with CSS, Individual Transforms, SVG, DOM attributes and JS Objects. Approach: A jQuery plugin that allows you to animate CSS properties based on distance to an object. CSS Spritesheet Animation Example: Sprite Sheet animation with CSS3 using the steps() feature. Caat: Scene graph director-based animation framework for javascript. CanvasScript3: CanvasScript3 is a Javascript library for the new HTML5 Canvas with an interface similar to ActionScript3. This library enables Sprite Groups, Layers, Mouse Events, Keyboard Events, Bitmap Effects, Tween Animations etc. Collie: Collie is a Javascript library that helps to create highly optimized animations and games using HTML 5. Collie runs on both PC and mobile using HTML 5 canvas and DOM. Emile.js: Emile.js is a no-frills stand-alone CSS animation JavaScript framework. Firmin: Firmin is a JavaScript animation library using CSS transforms and transitions. GreenSock Animation Platform: GreenSock Animation Platform is a suite of tools for scripted animation. Codepen Repository: Codepen repository with examples of Greensock usage and code. Examples: Here are a couple of examples demonstrating the core features of the Greensock Animation Platform. Learning Center: Tutorials and videos for GreenSock Animation Platform. JQuery Transit: Super-smooth CSS3 transformations and transitions for jQuery. Janis: Janis is a lightweight Javascript framework that provides simple animations via CSS transitions for modern browsers on the web as well as mobile devices. Keanu: Keanu is a micro-lib for animation on Canvas/JS. Magic: CSS3 Animations with special effects. Move.js: Move.js is a small JavaScript library making CSS3 backed animation extremely simple and elegant. Ramjet: Ramjet makes it looks as though one DOM element is capable of transforming into another, no matter where the two elements sit in the DOM tree. Rekapi: A keyframe animation library for JavaScript. SVG.js: A lightweight library for manipulating and animating SVG. Scripty2: scripty2 is a powerful, flexible JavaScript framework to help you write your own delicious visual effects & user interfaces. Shifty: Shifty is a tweening engine built in JavaScript. It is designed to fit any number of tweening needs. Snap.svg: Snap.svg JavaScript library makes working with your SVG assets as easy as jQuery makes working with the DOM. Stylie: Stylie is a fun tool for easily creating complex CSS animations. Quickly design your animation graphically, grab the generated code and go! Textillate.js: Textillate.js combines some awesome libraries to provide a ease-to-use plugin for applying CSS3 animations to any text. Tween.js: Super simple, fast and easy to use tweening engine which incorporates optimised Robert Penner's equations. Twitter Fave Animation: Rather than rely on CSS transitions, the new animation makes use of a series of images. Here's how to recreate the animation using the CSS animation steps timing function. Web Animation Past, Present, and Future (2016): Rachel Nabors explores the world of web animation standards, platforms and tools in 2016: SVG, SMIL, GreenSock AP, Framer, Browser Tooling etc. Web Animations API: Web Animations is a new JavaScript API for driving animated content on the web. By unifying the animation features of SVG and CSS, Web Animations unlocks features previously only usable declaratively, and exposes powerful, high-performance animation capabilities to developers. Are we animated yet?: This page tracks the progress of implementing the Web Animations API in Firefox. WAAPI Browser Support Test (+ Polyfill): This codepen tests whether and to which extend your browser supports Web Animations API. The test is run after including the Polyfill. Web Animations Polyfill: JavaScript implementation of the Web Animations API. Typography: The style, arrangement, or appearance of typeset matter. A Comprehensive Guide to Font Loading Strategies: Zach Leatherman describes different approaches to loading of web fonts. Adobe Edge Web Fonts: Edge Web Fonts is a free service that provides access to a large library of fonts for your website. It's one of the Edge Tools & Services from Adobe. Use of the service is free and unlimited. Baseline.js: A simple jQuery plugin for restoring vertical baselines thrown off by odd image sizes. CSS Typography cheat sheet: Small roundup on CSS features that will enhance your web typography. Convincing a browser to load fonts from other domains: A StackOverflow question about loading fonts across domains. FitText: FitText makes font-sizes flexible. Use this plugin on your fluid or responsive layout to achieve scalable headlines that fill the width of a parent element. FlowType.JS: Font-size and line-height based on element width. Fontmatrix: Matrix of fonts bundled with Mac and Windows operating systems, Microsoft Office and Adobe Creative Suite. Google Fonts: Google Fonts makes it quick and easy for everyone to use web fonts. Our goal is to create a directory of web fonts for the world to use. Our API service makes it easy to add Google Fonts to a website in seconds. Gutenberg: Gutenberg is a flexible and simple-to-use web typography starter kit for web designers and developers. Lettering.js: Web type is exploding all over the web but CSS currently doesn't offer complete down-to-the-letter control. So we created a jQuery plugin to give you that control. OpenFoundry: A platform for open-source fonts in a noise-free environment; to highlight their beauty and encourage further exploration. Pure Typography: CSS Styles for nicer web type. Depends on Pure. Quick guide to webfonts via @font-face: The @font-face feature from CSS3 allows us to use custom typefaces on the web in an accessible, manipulable, and scalable way. Truly Fluid Typography With vh And vw Units: This article describes viewport units and other technics to achieve typography which resizes smoothly with the screen. TypeButter: TypeButter allows you to set optical kerning for any font on your website. If you're longing for beautifully laid out text that today' browsers just don't provide, this is the plugin for you. Typeset.css: A no-nonsense CSS typography reset for styling user-generated content like blog posts, comments, and forum content. Typeset.css: A Sass library that provides some sensible default styles, optional classes to use & extend as needed, and some utility functions & mixins to make elevating your typography simpler. bacon: Bacon is a jQuery plugin that allows you to wrap text around a bezier curve or a line. slabText: A jQuery plugin for producing big, bold & responsive headlines. trunk8: trunk8 is an intelligent text truncation plugin to jQuery. When applied to a large block of text, trunk8 will cut off just enough text to prevent it from spilling over. Visualization: Placing data in a visual context. Bonsai.js: A lightweight graphics library with an intuitive graphics API and an SVG renderer. Chart.js: Simple, clean and engaging charts for designers and developers. Crossfilter: Crossfilter is a JavaScript library for exploring large multivariate datasets in the browser. Cube: Cube is a system for collecting timestamped events and deriving metrics. By collecting events rather than metrics, Cube lets you compute aggregate statistics post hoc. Cubism.js: Cubism.js is a D3 plugin for visualizing time series. Use Cubism to construct better realtime dashboards, pulling data from Graphite, Cube and other sources. D3.js: D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. DataMaps: Customizable SVG (world) map visualizations for the web in a single Javascript file using D3.js. Interactive Introduction to D3: D3 slides in D3 that I put together after becoming frustrated with explaining D3 using PowerPoint. NVD3: This project is an attempt to build re-usable charts and chart components for d3.js without taking away the power that d3.js gives you. Tutorial: Introduction to D3: Basically we just plot hidden circles randomly on the screen, and then transition them to a portion of the screen. Then we add some interaction to it so that the circles will move once you move your mouse over them. xCharts: xCharts is a JavaScript library for building beautiful and custom data-driven chart visualizations for the web using D3.js. Using HTML, CSS, and SVG, xCharts are designed to be dynamic, fluid, and open to integrations and customization. Easy Pie Chart: Easy pie chart is a jQuery plugin that uses the canvas element to render simple pie charts for single values Flot: Flot is a pure JavaScript plotting library for jQuery, with a focus on simple usage, attractive looks and interactive features. Google Chart Tools: The Google Visualization API allows you to create charts and reporting applications over structured data and helps integrate these directly into your website. Paper.js: Paper.js offers a clean Scene Graph / Document Object Model and a lot of powerful functionality to create and work with vector graphics and bezier curves. Photon: Photon is a JavaScript library that adds simple lighting effects to DOM elements in 3D space. Piecon: A tiny javascript library for dynamically generating progress pie charts in your favicons. Processing.js: Processing.js is the sister project of the popular Processing visual programming language, designed for the web. Processing.js makes your data visualizations work using web standards. Smoothie Charts: A JavaScript Charting Library for Streaming Data. TimelineJS: TimelineJS is an open-source tool that enables anyone to build visually rich, interactive timelines. Timesheet.js: Visualize your data and events with sexy HTML5 and CSS3. Create simple time sheets with sneaky JavaScript. Style them with CSS and have mobile fun as well. Treefun by Jim Blackler: This tool creates SVG (Standard Vector Graphics) files to illustrate information structured as a basic tree. jQuery.Gantt: Draw Gantt charts with the famous jQuery ease of development. jStat: jStat is a statistical library written in JavaScript that allows you to perform advanced statistical operations without the need of a dedicated statistical language (e.g. MATLAB or R). morris.js: Morris.js is a very simple API for drawing line, bar, area and donut charts. mxgraph: mxGraph is a JavaScript diagramming library that enables interactive graph and charting applications to be quickly created that run natively in any major browser, both HTML 5 capable and Internet Explorer v7+. three.js: Three.js is a library that makes WebGL - 3D in the browser - easy to use. While a simple cube in raw WebGL would turn out hundreds of lines of Javascript and shader code, a Three.js equivalent is only a fraction of that. vis.js: Vis.js is a dynamic, browser based visualization library. The library is designed to be easy to use, handle large amounts of dynamic data, and enable manipulation of the data. Architecture High level structure of the frontend code and the discipline of creating such structures. Algorithms: A self-contained step-by-step set of operations to be performed. Algorithms perform calculation, data processing, and/or automated reasoning tasks. Algorithm Visualizer: A collection of algorithms with code and visualizations for each one of them. Sorting Algorithms Animations: The following animations illustrate how effectively data sets from different starting points can be sorted using different algorithms. Design Patterns: Best practices that the programmer can use to solve common problems when designing an application or system. CSS Modules: A CSS Module is a CSS file in which all class names and animation names are scoped locally by default. CSS Modules Documentation: General overview and some implementations. ES CSS Modules: PostCSS plugin that combines CSS Modules and ES Imports. Tree Shaking Bootstrap: Jacob Parker describes how to include only those parts of Bootstrap you are really using on your website by leveraging CSS modules and ES6 modules. Components: Reusable and composable pieces of HTML, CSS and/or JavaScript code which are mostly used for GUI elements. Component Check: In this project Donald Pipowitch compares the usage and development of components in several frameworks such as Angular, Ember, Cycle.js and React. Container Components: Container Components is a pattern which allows to separate data-fetching and rendering concerns and increase the reusability of the (child) components. Devbridge Styleguide: Devbridge Styleguide helps you create, share, and automate a living visual style library of your brand. Presentational and Container Components: Dan Abramov creates a pattern for separating presentational and container components to increase reusability and clarity of the application code. Web Components: Web Components is a W3C standard for encapsulated, reusable and composable widgets for the web platform. Are We Componentized Yet?: Tracking the progress of Web Components through standardisation, polyfillification and implementation. Custom Elements: Eric Bidelman describes how to create new HTML elements and manage their life cycle. Custom Elements W3C Editor's Draft: This specification describes the method for enabling the author to define and use new types of DOM elements in a document. HTML Imports W3C Editor's Draft: HTML Imports are a way to include and reuse HTML documents in other HTML documents. HTML Imports: #include for the web: Eric Bidelman describes how to use HTML imports and goes through several edge cases. HTML's New Template Tag: The template element allows you to declare fragments of DOM which are parsed, inert at page load, and instantiated later at runtime. Shadow DOM 101: Dominic Cooney shows you how to use Shadow DOM in this tutorial. Shadow DOM 201: Eric Bidelman explains advanced topics related to styling of Shadow DOM elements. Shadow DOM 301: Eric Bidelman talks about advanced Shadow DOM topics like multiple shadow roots, insertion points, event model and Shadow DOM Visualizer. Shadow DOM W3C Editor's Draft: This specification describes a method of combining multiple DOM trees into one hierarchy and how these trees interact with each other within a document, thus enabling better composition of the DOM. ShadowDOM Visualizer: This tool allows you to visualize how Shadow DOM renders in the browser. Why Web Components Are So Important: Leon Revill compares web components with concepts from different frameworks and explains why web components matter. Write Web Components with ES2015 (ES6): This tutorial shows how to create a web component using ES2015 and how to make use of babel to transpile back to ES5. DOM Diffing & Patching: Diffing & Patching is a pattern which allows faster and simpler rendering and updating of DOM trees as manual manipulation à la jQuery. Change And Its Detection In JavaScript Frameworks: This article explores several approaches to manage state: Ember's data binding, Angular's dirty checking, React's virtual DOM, and its relationship to immutable data structures. Cito.js: The core of cito.js consists of a virtual DOM library inspired by React/Mithril. On top of that, it will provide a component framework which will make it easy to build well-encapsulated components. Incremental DOM: Incremental DOM is a library for building up DOM trees and updating them in-place when data changes. It differs from the established virtual DOM approach in that no intermediate tree is created (the existing tree is mutated in-place). Introducing Incremental DOM: Incremental DOM is a library inspired by Virtual DOM developed at Google. Morphdom: Lightweight module for morphing an existing DOM node tree to match a target DOM node tree. It's fast and works with the real DOM—no virtual DOM here! React Demystified: This article is an attempt to explain the core ideas behind React.js and Virtual DOM. React vs Incremental DOM vs Glimmer: In this post we will explore three technologies to build dynamic DOMs. We will also run benchmarks and find out which one is faster. React-less Virtual DOM with Snabbdom: functions everywhere!: Yassine Elouafi shows in this post how to write a virtual DOM based applications using a small and standalone library. Snabbdom: A virtual DOM library with focus on simplicity, modularity, powerful features and performance. Virtual DOM: Virtual-dom is a collection of modules designed to provide a declarative way of representing the DOM for your app. So instead of updating the DOM, you simply create a virtual tree or VTree, which looks like the DOM state that you want. html-to-vdom: This is yet another library to convert HTML into a vtree. It's used in conjunction with virtual-dom to convert template based views into virtual-dom views. html2hyperscript: Automatically translate old HTML markup into the new Hyperscript markup embeddable directly inside your component Javascript code. vdom-to-html: Turn Virtual DOM nodes into HTML. vdom-virtualize: Turn a DOMNode into a virtual-dom node. virtual-html: Convert given HTML into Virtual DOM object. vtree-select: Select vtree nodes (used by virtual-dom) using css selectors. Selector matching is done using cssauron. See the documentation for details on supported selectors. Design Pattern Collections: Overview resources and collections of design patterns. About HTML Semantics and Frontend Architecture: A collection of thoughts, experiences, ideas on HTML semantics, components and approaches to front-end architecture, class naming patterns, and HTTP compression. Box Tech Talk: Scalable JavaScript Application Architecture: A video by Nicholas Zakas (2012) about JavaScript Architecture. Learning JavaScript Design Patterns: In this free book Addy Osmani explores applying both classical and modern design patterns to the JavaScript programming language. Patterns For Large-Scale JavaScript Application Architecture: An extensive overview by Addy Osmani of existing architectural solutions in the frontend development field. Scalable JavaScript Application Architecture: In this video (2011) Nicholas Zakas discusses frontend architecture for complex, modular web applications with significant JavaScript elements. Single Page Apps in Depth: This free book is what I wanted when I started working with single page apps. It's not an API reference on a particular framework, rather, the focus is on discussing patterns, implementation choices and decent practices. JavaScript Modules: Modules divide programs into clusters of code that, by some criterion, belong together. Chapter 10 of Eloquent JavaScript: Modules: This chapter explores some of the benefits that division of code provides and shows techniques for building modules in JavaScript. ES6 In Depth: Modules: This article highlights export and import keywords from ES6. Efficient Module Loading Without Bundling: We can combine ES2015 modules, static analysis of those modules, HTTP/2, caching, Service Workers and a bloom-filter to create a server-client relationship where the client can efficiently load any module. JavaScript Modules: A Beginner's Guide: In this post, Preethi Kasireddy will unpack the buzzwords like module bundlers, AMD and CommonJS for you in plain English, including a few code samples. Modern Modular JavaScript Design Patterns: A chapter from Essential JavaScript Design Patterns on Modules. Module Bundlers and Loaders: Libraries for bundling JavaScript Modules into one or several files. Browserify: Browserify lets you require('modules') in the browser by bundling up all of your dependencies. Budo: A browserify development server, focused on incremental reloading, LiveReload integration (including CSS injection), and other high-level features. Watchify: Watch mode for browserify builds. CrapLoader: The goal of crapLoader is to load ads, widgets or any JavaScript code with document.write in it. This library hijacks document.write and delegates the content loaded from each script into the correct position. Modules Webmake: A CommonJS module bundler similar to Browserify but much faster due to different requirements finder. Require.js: RequireJS is a JavaScript file and AMD module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments. Require1k: CommonJS require for the browser in 1KB, with no build needed. Rollup.js: Rollup is a next-generation JavaScript module bundler. Author your app or library using ES2015 modules, then efficiently bundle them up into a single file for use in browsers and Node.js. SystemJS: Universal dynamic module loader - loads ES6 modules, AMD, CommonJS and global scripts in the browser and NodeJS. Works with both Traceur and Babel. Modular JavaScript: A Beginners Guide to SystemJS & JSPM: The combination of jspm and SystemJS provides a unified way of installing and loading dependencies. URequire: The Ultimate JavaScript Module Builder & Automagical Task Runner. Webpack: Webpack is a module bundler. It takes modules with dependencies and generates static assets representing those modules. Block, Element, Modifying Your JavaScript Components: Mark Dalgleish is discussing how to organize React code with BEM and build everything with Webpack. Developing with Docker and Webpack: Chris Harrington explains how to create a development environment with Webpack and Docker to match the production as much as possible. Full-Stack Redux Tutorial: We will go through all the steps of constructing a Node+Redux backend and a React+Redux frontend for a real-world application, using test-first development. How to Set Up Webpack Image Loader: This brief tutorial will help you set up an image loader in Webpack. The SoundCloud Client in React + Redux: After finishing this step by step tutorial you will be able to author your own React + Redux project with Webpack and Babel. Webpack from Apprentice to Master: The purpose of this guide is to help you get started with Webpack and then go beyond basics. WebpackBin: A webpack code sandbox. Why I think Webpack is the Right Approach To Build Pipelines: Thomas Boyt compares how Grunt, Gulp, Broccoli and Webpack discover dependencies. UMD (Universal Module Definition): This repository formalizes the design and implementation of the Universal Module Definition (UMD) API for JavaScript modules. These are modules which are capable of working everywhere, be it in the client, on the server or elsewhere. Writing Modular JavaScript With AMD, CommonJS & ES Harmony: In this article Addy Osmani reviewes several of the options available for writing modular JavaScript using modern module formats AMD, CommonJS and ES6 Modules. Observable: An Observable is an event stream which can emit zero or more events, and may or may not finish. If it finishes, then it does so by either emitting an error or a special “complete” event. ECMAScript Observable: This proposal introduces an Observable type to the ECMAScript standard library. The Observable type can be used to model push-based data sources such as DOM events, timer intervals, and sockets. Reactive Extensions (RxJS): RxJS is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators. Async JavaScript with Reactive Extensions: Jafar Husain explains in this video how Netflix uses the Reactive Extensions (Rx) library to build responsive user experiences that strive to be event-driven, scalable and resilient. Exploring Rx Operators: FlatMap: Christoph Burgdorf introduces the FlatMap operator and its usage for collections and observables. Exploring Rx Operators: Map: Christoph Burgdorf explains how to use the map operator in RxJS. Functional Core Reactive Shell: Giovanni Lodi makes an overview of different architecture meta-patterns and describes his current findings about functional programming and observables as a way to control side effects. Learn RX: A series of interactive exercises for learning Microsoft's Reactive Extensions (Rx) Library for Javascript. Learn RxJS: This site focuses on making RxJS concepts approachable, the examples clear and easy to explore, and features references throughout to the best RxJS related material on the web. Real World Observables: Sergi Mansilla writes an FTP client to use it as an example for a real world application based on RxJS. Rx Training Games: Rx Training Games is a coding playground that can be used to learn and practice Reactive Extensions coding grid-based games Rx-Book: A complete book about RxJS v.4.0. RxMarbles: A webapp for experimenting with diagrams of Rx Observables, for learning purposes. RxState: Simple opinionated state management library based on RxJS and Immutable.js Taking Advantage of Observables in Angular 2: Christoph Burgdorf describes the advantages of Observables and how you can use them in Angular 2 context. Transducers with Observable Sequences: A chapter from the RxJS Book describing Transducers. Why We Built Xstream: The authors needed a stream library tailored for Cycle.js. It needs to be “hot” only, small in kB size and it should have only a few and intuitive operators. Routing: A routing system parses a string input (usually a URL) and decides which action should be executed by matching the string against multiple patterns. A JavaScript router in 20 lines: Joakim Carlstein shows how to write a simple router with data binding. Crossroads.js: Crossroads.js is a powerful and flexible routing system. If used properly it can reduce code complexity by decoupling objects and also by abstracting navigation paths and server requests. Director: A tiny and isomorphic URL router for JavaScript. Encapsulated Routing with Elements: Peter Burns describes a routing approach based on Polymer elements, that allow to create chained and modular routes. Hash.js: Hash.js is a 0.5 KB script that lets you manipulate everything behind # in urls. JQuery Address: The jQuery Address plugin provides powerful deep linking capabilities and allows the creation of unique virtual addresses that can point to a website section or an application state. Page.js: Micro client-side router inspired by the Express router. Roadcrew.js: Roadcrew.js is a small JavaScript component which lets you switch pages of a single file website. Route Recognizer: A lightweight JavaScript library that matches paths against registered routes. It includes support for dynamic and star segments and nested handlers. Router.js (Ember): Router.js is the routing microlib used by Ember.js. Router5: A simple, powerful, modular and extensible router, organising your named routes in a tree and handling route transitions. In its simplest form, Router5 processes routing instructions and outputs state updates. UI Data Binding: Binding of UI elements to an application domain model. Most frameworks employ the Observer pattern as the underlying binding mechanism. Bindings in Ember: Unlike most other frameworks that include some sort of binding implementation, bindings in Ember.js can be used with any object. Change And Its Detection In JavaScript Frameworks: This article explores several approaches to manage state: Ember's data binding, Angular's dirty checking, React's virtual DOM, and its relationship to immutable data structures. Easy Two-Way Data Binding in JavaScript: Two-way data binding refers to the ability to bind changes to an object's properties to changes in the UI, and viceversa. This article describes how to implement data binding with vanilla JavaScript. Functional Reactive Bindings: A CommonJS package that includes functional and generic building blocks to help incrementally ensure consistent state. Knockout.js: Knockout is a standalone JavaScript implementation of the Model-View-ViewModel pattern with templates. Rivets.js: Lightweight and powerful data binding + templating solution for building modern web applications. Synapse: Hooks to support data binding between virtually any object. Unidirectional Data Flow: An architecture design pattern which promotes a flow of data and events in a single direction, usually creating an interactive loop. Flux: Flux is the application architecture that Facebook uses for building client-side web applications. It complements React's composable view components by utilizing a unidirectional data flow. It's more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code. Fluxiny: ~1K implementation of flux architecture Immutable User Interfaces: Lee Byron talks about unidirectional data flow architectures based on immutable data structures in contrast to traditional MVC based designs. Immutable.js: Immutable persistent data collections for Javascript which increase efficiency and simplicity. MobX: MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming. Model-View-Intent (MVI): MVI is a unidirectional data flow architecture pattern consisting of three parts: Intent (to listen to the user), Model (to process information), and View (to output back to the user). MVI in Cycle.js Docs: André Staltz describes how to refactor an application into MVI pattern. Model-View-Intent with React and RxJS: Satish Chilukuri shows an example implementation of MVI pattern with React. Reactive MVC and the Virtual DOM: André Staltz describes the idea of Reactive Programming vs. Interactive Programming, proceeds with the MVI design pattern and compares it to React/Flux. What Developers Need to Know about MVI (Model-View-Intent): The article explains the general MVI pattern and how it relates to React, Reactive Programming and Cycle.js Nothing New in React and Flux Except One Thing: Andre Staltz talks about aspects of React and Flux which make them innovative and compelling. Redux: Redux is a predictable state container for JavaScript apps. It attempts to make state mutations predictable by imposing certain restrictions on how and when updates can happen. Building Redux in TypeScript with Angular 2: In this post we're going to discuss the ideas behind Redux. How to build our own mini version of the Redux Store and hook it up to Angular 2. Exploring Redux Middleware: The author explains how to author your own middleware for Redux. He dives into the execution path of each middleware function in the chain and shows some examples. Full-Stack Redux Tutorial: We will go through all the steps of constructing a Node+Redux backend and a React+Redux frontend for a real-world application, using test-first development. Immutable.js: Immutable persistent data collections for Javascript which increase efficiency and simplicity. Learn Redux: A video series by Wes Bos, teaching Redux. From setting up Webpack to using Dev Tools. Normalizr: Normalizes deeply nested JSON API responses according to a schema for Flux and Redux apps. Redux Actions: Flux Standard Action utilities for Redux. Redux Form: A Higher Order Component using react-redux to keep form state in a Redux store. Redux Loop: A port of elm-effects and the Elm Architecture to Redux that allows you to sequence your effects naturally and purely by returning them from your reducers. Redux Saga: An alternative Side Effects middleware for Redux applications. Instead of dispatching Thunks which get handled by the redux-thunk middleware, you create Sagas to gather all your Side Effects logic in a central place. Redux Tutorial: This repository contains a step by step tutorial to help grasp flux and more specifically Redux. Reinventing Flux - Interview with Dan Abramov: Dan talks about why he developed Redux. Reselect: Simple “selector” library for Redux inspired by getters in NuclearJS and subscriptions in re-frame. Some Problems with React/Redux: André Staltz goes through the pros and cons of React + Redux. Testing a React & Redux Codebase: This series aims to be a very comprehensive guide through testing a React and Redux codebase, where you can really cover a lot with just unit tests because the code is mostly universal. The Redux Ecosystem: Let's take a look at most of the features that you'll have to deal with when the time comes, — and where React & Redux themselves can't help you. The Redux Journey at react-europe 2016: In this talk, Dan Abramov reflects on the past, present, and future of Redux. The SoundCloud Client in React + Redux: After finishing this step by step tutorial you will be able to author your own React + Redux project with Webpack and Babel. Tic-Tac-Toe.js: Redux Pattern in Plain JavaScript: Ramon Victor describes how to use Redux with vanilla JavaScript. No React, no jQuery, no micro-library, it doesn't rely on anything else. It's just plain JS. Understanding Redux Middleware: The author describes the functional programming concepts involved in the creation and application of middleware functions. Unidirectional Data Flow Architectures (Talk): Andre Staltz compares modern architecture patterns including Flux, Redux, Model-View-Intent, Elm Arch and BEST. Designs: Ready to use and well documented structures and frameworks for frontend development. Atomic Design: Atomic Design discusses the importance of crafting robust design systems, and introduces a methodology for which to create smart, deliberate interface systems. A More Seamless Workflow — Style Guides for Better Design and Development: Ash Connolly explains what styles guides are and which benefits they bring to designers and developers. Atomic Docs: Atomic Docs is a styleguide generator and component manager. Atomic Docs is built in PHP. Inspired by Brad Frost's Atomic Design principles. Atomic Lab: Template sharing and coding environment based on atomic design. Authoring jQuery Plugins: jQuery is an utility library and a plugin framework. This section collects resources about creating such plugins. Advanced Plugin Concepts: A collection of best practices for jQuery plugin authoring. How to Create a Basic Plugin: The article describes basic plugin creation and provides a simple boilerplate. Signs of a poorly written jQuery plugin: Collection of jQuery plugin antipatterns. The Ultimate Guide to Writing jQuery Plugins: A comprehensive guide on how to develop jQuery plugins including a simple boilerplate. Writing Stateful Plugins with the jQuery UI Widget Factory: The article demonstrates the capabilities of the Widget Factory by building a simple progress bar plugin. jQuery Boilerplate: This project won't seek to provide a perfect solution to every possible pattern, but will attempt to cover a simple template for beginners and above. jQuery Plugin Patterns: This project won't seek to provide implementations for every possible pattern, but will attempt to cover popular patterns developers often use in the wild. Block Element Modifier (BEM): Methodology aimed at achieving fast to develop long-lived projects, team scalability, and code reuse. A New Front-End Methodology: BEM: An introduction by Varvara Stepanova at SmashingMagazine. An Introduction to the BEM Methodology: General introduction article on tutsplus. BEM 101: A collaborative post by Joe Richardson, Robin Rendle, and CSS-Tricks staff giving an introduction to BEM with some good examples. BEM I (finally) understand: In this article Andrei Popa will focus on the basics of BEM and how to approach simple to complex anatomies. Battling BEM (Extended Edition): 10 Common Problems And How To Avoid Them: This article aims to be useful for people who are already BEM enthusiasts and wish to use it more effectively or people who are curious to learn more about it. Block, Element, Modifying Your JavaScript Components: Mark Dalgleish is discussing how to organize React code with BEM and build everything with Webpack. Emmet filter for BEM: If you're writing your HTML and CSS code in OOCSS-style, Yandex's BEM style specifically, you will like this filter. It provides some aliases and automatic insertions of common block and element names in classes. Fifty Shades of BEM: Article describes different flavors of BEM. How We Use BEM to Modularise Our CSS: Andrei Popa describes the challenges, AlphaSights team had, implementing BEM in their projects. Introduction To BEM Methodology (Toptal): General introduction to BEM methodology and platform. MindBEMding – getting your head 'round BEM syntax: Article on csswizardry explaining the BEM syntax for CSS classes. Pobem: PostCSS plugin for BEM syntax. Support for BEM modules in Sass 3.3: The next major release of Sass is poised for release and with it comes real support for BEM-style modules... To BEM or not to BEM: A series of interviews on BEM methodology. Cycle.js: A functional and reactive JavaScript framework that solves the cyclic dependency of Observables which emerge during dialogues (mutual observations) between the Human and the Computer. Async Driver: Higher order factory for creating cycle.js async request based drivers. Allows you almost completely eliminate boilerplate code for this kind of drivers. Cycle.js Was Built to Solve Problems: In this video André Staltz shows how Cycle.js has a practical purpose, meant to solve problems your customers/business may relate to. Cycle.js and Functional Reactive User Interfaces: In this talk we will discover how Cycle.js is purely reactive and functional, and why it's an interesting alternative to React. Draw Cycle: Simple Cycle.js program visualized Drivers: Drivers are functions that listen to Observable sinks (their input), perform imperative side effects, and may return Observable sources (their output). Animation: A Cycle driver for requestAnimationFrame. Audio Graph Driver: Audio graph driver for Cycle.js based on virtual-audio-graph. Cookie: Cycle.js Cookie Driver, based on cookie_js library. DOM: The standard DOM Driver for Cycle.js based on virtual-dom, and other helpers. Fetch: A Cycle.js Driver for making HTTP requests, using the Fetch API. Fetcher: A Cycle.js Driver for making HTTP requests using stackable-fetcher. Firebase: Thin layer around the firebase javascript API that allows you to query and declaratively update your favorite real-time database. HTTP: A Cycle.js Driver for making HTTP requests, based on superagent. Hammer.js: The driver incorporates the Hammer.js gesture library. History: Cycle.js URL Driver based on the rackt/history library. Keys: A Cycle.js driver for keyboard events. Mongoose.js: A driver for using Mongoose with Cycle JS. Accepts both, write and read operations. Notification: A Cycle.js Driver for showing and responding to HTML5 Notifications. Router: A router built from the ground up with Cycle.js in mind. Stands on the shoulders of battle-tested libraries switch-path for route matching and rackt/history for dealing with the History API. Router5: A source/sink router driver for Cycle.js, based on router5. Server-Sent Events: Cycle.js driver for Server-Sent Events (SSE), a browser feature also known as EventSource. Server-Sent Events allow the server to continuously update the page with new events, without resorting to hacks like long-polling. Snabbdom: Alternative DOM driver utilizing the snabbdom library. Socket.IO: A Cycle driver for applications using Socket.IO Storage: A Cycle.js Driver for using localStorage and sessionStorage in the browser. Example Projects: Example applications built with Cycle.js Cycle.js Examples: Browse and learn from examples of small Cycle.js apps using Core, DOM Driver, HTML Driver, HTTP Driver, JSONP Driver, and others. RX Marbles: Interactive diagrams of Rx Observables. TODO: Minimum Viable Pizza: Minimum Viable Pizza implemented with Cycle.js Tricycle: A scratchpad for trying out Cycle.js. Intro to Functional Reactive Programming with Cycle.js: Nick Johnstone gives an introduction to developing with Cycle.js in this video presentation. Learning How to Ride: an Introduction to Cycle.js: In this talk, Fernando Macias Pereznieto introduces us to the good, the bad, and the beautiful of using Cycle.js, whether you are a complete beginner or an experienced JS ninja. Motorcycle.js: This is a sister project that will continue to evolve and grow alongside Cycle.js for the foreseeable future. The primary focus of this project is to tune it for performance as much as possible. Most: Monadic reactive streams with high performance. Plug and Play All Your Observable Streams With Cycle.js: Frederik Krautwald explains the principles behind Cycle.js, it's inner workings and how to use it to create a simple program with drivers. Tricycle: A scratchpad for trying out Cycle.js. What Developers Need to Know about MVI (Model-View-Intent): The article explains the general MVI pattern and how it relates to React, Reactive Programming and Cycle.js Polymer Project: The Polymer library is designed to make it easier and faster for developers to create great, reusable components for the modern web. Building web components using ES6 classes: Web components evolve markup into something that's meaningful, maintainable, and highly modular. Thanks to these new API primitives, not only do we have improved ergonomics when building apps, but we gain better overall structure, design, and reusability. Developing Front-End Microservices: In this article series we'll go through Web Components development in context of microservices. Lazy Loading of Pages: iron-lazy-pages is a Polymer component which allows to load pages on demand. ShadowDOM Visualizer: This tools allows you to visualize how Shadow DOM renders in the browser. Thinking in Polymer (The Polymer Summit 2015): Kevin Schaaf explains how to employ data binding and composition to build complex application using only Polymer. Unidirectional Dataflow Architecture with Polymer + RxJS + Immutable Data: Richard Anaya describes how to combine Polymer, RxJS and Freezer to implement a unidirectional data flow architecture. Using Elements: This guide describes how to install and use standalone Polymer components in an existing project. Using Polymer with Flux and a Global App State: Paulus Schoutsen describes his experience integrating Polymer and NuclearJS. What is shady DOM?: On browsers that support shadow DOM, it's possible to have an element that is rendered with complex DOM, but have that complexity hidden away as implementation detail. SMACSS: SMACSS (pronounced “smacks”) is a way to examine your design process and as a way to fit those rigid frameworks into a flexible thought process. It is an attempt to document a consistent approach to site development when using CSS. T3: T3 is a minimalist JavaScript framework sponsored by Box Inc. that provides core structure to code. The Elm Architecture: The Elm Architecture is a simple pattern for infinitely nestable components. It is great for modularity, code reuse, and testing. TodoMVC: A project which offers the same Todo application implemented using MV* concepts in most of the popular JavaScript MV* frameworks of today. Event-Driven Programming: Event-driven programming is a programming paradigm in which the flow of the program is determined by events such as user actions, sensor outputs, or messages from other programs/threads. Comparison Between Different Observer Pattern Implementations: The comparison below is just about the basic features of subscribing to an event type, dispatching and removing an event listener. Event Emitter, Pub Sub or Deferred Promises: In this post Pete Otaqui explores a little about how each pattern works with (very) basic implementations and looks at the reasons why you might choose one over another. Implementations: Libraries, frameworks and tools that use Event-Driven Programming paradigm. Bacon.js: A small functional reactive programming lib for JavaScript. Turns your event spaghetti into clean and declarative feng shui bacon, by switching from imperative to functional. Flight: An event-driven web framework, from Twitter. Mediator.js: Mediator is a simple class that allows you to register, unregister, and call subscriber methods to help event-based, asyncronous programming. Postal.js: Postal.js takes the familiar "eventing-style" paradigm and extends it by providing "broker" and subscriber implementations Radio.js: Radio.js is a small dependency-free publish/subscribe JavaScript library. Use it to implement the observer pattern in your code to help decouple your application architecture for greater maintainability. js-signals: Custom Event/Messaging system for JavaScript. pubsub.js: A tiny (~600 bytes when minified, ~300 bytes when gzip'd) and robust pubsub implementation. Functional Programming: Functional programming is a programming paradigm, that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. A Gentle Introduction to Functional JavaScript: A 3 part series, by Derick Bailey featuring Chet Harrison, about functional programming with many examples in JavaScript. Monads, Monoids and Composition with Functional JavaScript: Chet Harrison explains monads using form validation as an example. Notes and Code from the Crowdcast: Chet Harrison provides a broad overview of functional programming concepts and a step by step tutorial for building Monads. The Basics of Functional Programming: In this first episode, you'll learn the basics of why functional programming, what it is, where it came from and what the core of it is. You'll see function composition, function purity, currying, higher order functions and first-class functions. A Million Ways to Fold in JS: Brian Lonsdorf provides many functional alternatives to loops in this video. Adventures in Functional Programming: A talk by Jim Weirich, demonstrating how to use functional programming and lambda calculus to derive Y combinator. Allong.es: allong.es is a JavaScript library based on the function combinator and decorator recipes introduced in the book JavaScript Allongé. Barely Functional: Tiny (2.7kb) functional programming library using native es5/6 operations. Basic Lazy Evaluation and Memoization in JavaScript: Memoization is a way of optimizing code so that it will return cached results for the same inputs. Bilby.js: A functional library based on category theory with immutable multimethods, functional data structures, functional operator overloading, automated specification testing. Composability: from Callbacks to Categories in ES6: The author borrows some ideas from functional languages to explore a different approach for addressing the callback hell. Curry or Partial Application?: Eric Elliott describes the difference between partial application and curry. Daggy: Library for creating tagged constructors with catamorphism. Date FP: Functional programming date manipulation library. Debugging Functional: This post will demonstrate a simple solution that can go a long way to enhance the debugging experience in functional JavaScript applications. Deterministic: A weekly digest of interesting news and articles covering functional programming for the web, especially on the front end. Example Projects: Open source projects which use functional programming, preferably point-free and side-effect-free. Async Problem: This project considers various approaches to the problem of concurrently reading files inside a directory and concatenating their contents. CommonJS module dependencies resolver: The module and all related modules are written using point-free style. Egg Hunt Server: A restful API written in FP style. Idealist: Functional HTTP micro-framework. Sanctuary Build Script: A build script for generating the Sanctuary website. FP DOM: A collection of functions to favor functional programming in a DOM context. Fantasy Combinators: Combinators which are used for fantasy-land projects. Fantasy Land: Specification for interoperability of common algebraic structures in JavaScript. Conformant Implementations: A list of libraries implementing the Fantasy Land specification. Fantasy Lenses: Composable, immutable getters and setters. Functional Concepts For JavaScript Developers: Currying: Andrew Robbins talks about what currying is and why it's useful. Functional Core Reactive Shell: Giovanni Lodi makes an overview of different architecture meta-patterns and describes his current findings about functional programming and observables as a way to control side effects. Functional Frontend Architecture: This repository is meant to document and explore the implementation of what is known as "the Elm architecture". A simple functional architecture for building frontend applications. Functional JavaScript Mini Book: Jichao Ouyang gives and introduction to functional programming with JavaScript and describes some Typeclasses like Functor and Monad. Functional Javascript Workshop: The goal of this workshop is to create realistic problems that can be solved using terse, vanilla, idiomatic JavaScript. Functional Principles In React: Jessica Kerr talks about four functional principles: Composition, Declarative Style, Isolation and Flow Of Data, and their usage in React. Functional Programming Jargon: Jargon from the functional programming world in simple terms. Functional Programming for JavaScript People: Chet Corcos explains different features of functional programming like composition, currying, lazy evaluation, referential transparency and compares Clojure with Haskell. Functional Refactoring in JavaScript: In this article Victor Savkin shows how to apply functional thinking when refactoring JavaScript code. He does that by taking a simple function and transforming it into a more extendable one, which has no mutable state, and no if statements. Functional.js: Functional.js is a functional JavaScript library. It facilitates currying and point-free / tacit programming and this methodology has been adhered to from the ground up. Functionize: A collection of functions which aids in making non-functional libraries functional. Futures and Monoids: Yassine Elouafi explains the nature of Monoids using Futures, Numbers and Strings as examples. Hey Underscore, You're Doing It Wrong!: In this talk Brian Lonsdorf gently takes a shot at underscore.js for not thinking about currying and partial function application in its library design. Immutability, Interactivity & JavaScript: We'll dive in and see how trees of JavaScript arrays can permit building efficient immutable collections. Then we'll see how embracing immutable values dramatically simplifies some classic hard problems in client side programming including but not limited to undo, error playback, and online/offline synchronization. Immutable Sequence.js: High performance implementation of Immutable Sequence in JavaScript, based on Finger Tree. Immutable.js: Immutable persistent data collections for Javascript which increase efficiency and simplicity. JSAir - Functional and Immutable Design Patterns in JavaScript: An episode of JavaScript Air about "the how and why of functional programming and immutable design patterns in JavaScript" with Dab Abramov and Brian Lonsdorf as guests. JavaScript and Type Thinking: Yassine Elouafi introduces Algebraic Data Types with an example of a simple and a recursive type. Javascript Combinators by Reginald Braithwaite: In this talk, we'll explore functions that consume and return functions, and see how they can be used to build expressive programs that hew closely to JavaScript's natural style. Lamda.js: This library takes all the methods on instances of strings, arrays, objects, numbers, and regexp's and turns them into functions that can be used in a pointfree way. Lenses Quick n' Dirty: A video by Brian Lonsdorf that introduces lenses. Lenses and Virtual DOM Support Open Closed: Hardy Jones explains how Lenses work using a simple example of working with Virtual DOM. Lenses.js: Composable kmett style lenses. Lodash/fp: The lodash/fp module is an instance of lodash with its methods wrapped to produce immutable auto-curried iteratee-first data-last methods. Making your JavaScript Pure: Jack Franklin compares pure and impure functions and describes how to leverage functional programming principles in JavaScript. Monads: Composable computation descriptions. The essence of monad is thus separation of composition timeline from the composed computation's execution timeline, as well as the ability of computation to implicitly carry extra data. Collections of Monads: Libraries of monad implementations. Akh: Akh includes a basic set of common monad transformers, along with monads derived from these transformers. Akh structures implement the Fantasy Land specification. Folktale: Folktale is a suite of libraries for generic functional programming in JavaScript that allows you to write elegant modular applications with fewer bugs, and more reuse. Monet.js: Monet is a tool bag that assists Functional Programming by providing a rich set of Monads and other useful functions. Continuation Monad: Represents computations in continuation-passing style (CPS). In continuation-passing style function result is not returned, but instead is passed to another function, received as a parameter (continuation). The Delimited Continuation Monad in Javascript: This post overviews continuations in Atum and covers the implementation of the delimited continuation monad in JavaScript. Either Monad: The Either type represents values with two possibilities: a value of type Either a b is either Left a or Right b. It is often used for error handling. Lazy Either: The LazyEither type is used to represent a lazy Either value. It is similar to the Future and Promise types. Practical Intro to Monads in JavaScript: Either: Jakub Strojewski describes the Either Monad, a tool for fast-failing, synchronous computation chains. Free Monad: A free monad satisfies all the Monad laws, but does not do any computation. It just builds up a nested series of contexts. The user who creates such a free monadic value is responsible for doing something with those nested contexts. Fantasy Frees: An implementation of Coyoneda, Yoneda, Trampoline, Free Monad and Free Applicative with usage examples. Free Monad Experiments by Hardy Jones: Coyoneda, Coproduct, Either, Free, State, AJAX and so on. Free Monads Video Series: A video series on free monads by Brian Lonsdorf explaining Coyoneda, Free Monad and Interpretors. Freeky: Collection of free monads by Brian Lonsdorf. Futures: Futures represent the value arising from the success or failure of an asynchronous operation (I/O). Fluture: The debuggable Fantasy Land Future library. Folktale Task: A structure for time-dependent values, providing explicit effects for delayed computations, latency, etc. From Callback to Future -> Functor -> Monad: Yassine Elouafi goes through a simple implementation of Futures and compares them to Promises. Future IO: A fantasy-land compliant monadic IO library for Node.js. Futurizer: Turn callback-style functions or promises into futures! Introduction: Introductory materials about monads. Monads in JavaScript: This article explains monads and their usage in JavaScript including Identity, Maybe, List, Continuation, Do notation and Chaining. Practical Intro to Monads in JavaScript: A simple, practical tutorial for JavaScript developers showing how some monads can be used. Understanding Monads With JavaScript: The author starts with a problem of dealing with explicit immutable state and solves it with JavaScript using monads. Maybe Monad: Using Maybe is a good way to deal with errors or exceptional cases without resorting to drastic measures such as error. It is a simple kind of error monad, where all errors are represented by Nothing. A richer error monad can be built using the Either type. A Gentle Intro to Monads … Maybe?: A short introduction to Maybe and the world of monads. A Monad in Practicality: First-Class Failures: This article shows how the Maybe monad can be used for handling simple failure use cases. It then extrapolates into complex failure scenarios and shows how these cases can be modelled in terms of the Either monad. Practical Intro to Monads in JavaScript: A simple, practical tutorial for JavaScript developers showing how some monads can be used. Reader Monad: Represents a computation, which can read values from a shared environment, pass values from function to function, and execute sub-computations in a modified environment. Don't Fear the Reader: Pascal Hartig explains how to use the reader monad in JavaScript. Fantasy Readers: Fantasy Land compatible implementation of the Reader Monad. LiveCoding Video of Reader Monad Implementation: In this video you will learn how to use and implement a Reader from scratch. Monad a Day: Reader: Short video by Brian Lonsdorf about the Reader Monad. Transformers: Special types that allow us to roll two monads into a single one that shares the behavior of both. Akh: Akh includes a basic set of common monad transformers, along with monads derived from these transformers. Akh structures implement the Fantasy Land specification. Fantasy ArrayT: Monad transformer for JavaScript Arrays. Monad Transformers: Monad transformers are tricky, they require an excessive amount of type juggling. One of the aims of this package is to reduce the amount of wrapping and unwrapping needed for making a new transformer and to provide an easy way to define and combine transformers. Monad Transformers Library: Practical monad transformers for JS. Validation Monad: A disjunction that is appropriate for validating inputs and aggregating failures. Folktale Validation: Validation Monad implementation of Folktale Library. Practical Intro to Monads in JavaScript: Validation: Jakub Strojewski shows how to accumulate errors in a simple Validation use case. Mori: A library for using ClojureScript's persistent data structures and supporting API from the comfort of vanilla JavaScript. Mostly Adequate Guide to Functional Programming: A book by Brian Lonsdorf that introduces algebraic functional programming in JavaScript. Nanoscope: Nanoscope is a javascript library designed to make complex transformations of data much easier. It is a built on the idea of a functional Lens - a construct that enables focusing on sub-parts of data structures to get and modify. Pointfree Fantasy: Point-free wrappers for fantasy-land. Functions are curried using lodash's curry function, and receive their data last. Gives us aliases with our familar haskell names as well. Pointfree Javascript: In this post Lucas Reis presents what is called pointfree style programming and goes through some common scenarios to demonstrate its benefits. Practical Functional Programming: Pick Two: James Coglan tries to show in this video how to use functional concepts in daily JavaScript programming. Promises + FP = Beautiful Streams: Yassine Elouafi show how to use functional programming and algebraic data types to derive a pure functional definition of reactive programming like streams. Pure JavaScript: Christian Johansen shows you how you can up your game by leaving loops behind and embracing functions as the primary unit of abstraction. Pure UI: Guillermo Rauch discusses the definition of an application's UI as a pure function of application state. PureScript: PureScript is a strongly, statically typed language which compiles to JavaScript. It is written in and inspired by Haskell. Ramda: A practical library designed specifically for a functional programming style, one that makes it easy to create functional pipelines, one that never mutates user data. Practical Ramda - Functional Programming Examples: Tom MacWright gives some practical examples of Ramda usage. Ramda Fantasy: Fantasy Land compatible types for easy integration with Ramda. This is an experimental project and will probably merge with Sanctuary. Sanctuary: Sanctuary is a functional programming library inspired by Haskell and PureScript. It depends on and works nicely with Ramda. Sanctuary makes it possible to write safe code without null checks. Sanctuary Build Script: A build script for generating the Sanctuary website. The Little Idea of Functional Programming: Jack Hsu tries to take a look at a couple of simple concepts that make up the little idea behind functional programming and to tie the concepts back to code examples in JavaScript. Timm: Immutability helpers with fast reads and acceptable writes. Transducers: Transducers are a powerful and composable way to build algorithmic transformations that you can reuse in many contexts."Transducers" Presentation at Strange Loop: This talk will describe transducers, a new library feature for Clojure (but of interest to other languages) that emphasizes composable, context-free, intermediate-free notions like 'mapping' and 'filtering' and their concrete reuse across all of the contexts above. Figuring out what transducers are good for: Tim Cuthbertson attempts some plausible but detailed examples with Transducers in JavaScript. Implementations: Libraries that implement Transducer protocoll and include ready to use transformers. Transduce: Implementation by Kevin Beaty extracted from underarm. Transducers-js by Cognitect Labs: A high performance Transducers implementation for JavaScript by Cognitect Labs. Transducers.js Library by James Long: A small library for generalized transformation of data (inspired by Clojure's transducers) Transducers.js Round 2 with Benchmarks: Refactored version of Transducers.js, some benchmarks, Laziness, the transformer protocoll. Transducers.js: A JavaScript Library for Transformation of Data: A post announcing the transducers.js library with some explanation. Streaming Logs with Transducers and Ramda: In this article we will use Ramda to parse a log file without curly braces (and introduce transducers along the way). Transducers Documentation for Clojure: Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Transducers Explained: Part 1: An introduction to transducers using JavaScript. We will work from reducing over arrays, to defining transformations as transformers, then incrementally introducing transducers and using them with transduce. Transducers Explained: Pipelines: In this article, we will introduce four new transducers: filter, remove, drop and take. We will show how transducers can be composed into pipelines and talk about the order of transformation. Transducers are Coming: The first announcement by Rich Hickey. Transducers with Observable Sequences: A chapter from the RxJS Book describing Transducers. Understanding Transducers in JavaScript: Roman Liutikov translated code examples from similar Clojure article into JavaScript. So you can still read the article and check code examples here. Union Type: Union types are a way to group different values together. Union-type is a small JavaScript library for defining and using union types. Functional Reactive Programming (FRP): FRP is a programming paradigm for asynchronous dataflow programming using the building blocks of functional programming. A General Theory of Reactivity: Kris Kowal describes popular primitives of Reactive Programming and some use cases. A General Theory of Reactivity (Video): Kris Kowal talks about reactive primitives and their traits. Controlling Time and Space: This talk will quickly cover the basics of FRP, and then go into a couple different formulations of FRP that people are beginning to use. We will explore how these formulations fit together historically and theoretically. Cycle.js: A functional and reactive JavaScript framework that solves the cyclic dependency of Observables which emerge during dialogues (mutual observations) between the Human and the Computer. Async Driver: Higher order factory for creating cycle.js async request based drivers. Allows you almost completely eliminate boilerplate code for this kind of drivers. Cycle.js Was Built to Solve Problems: In this video André Staltz shows how Cycle.js has a practical purpose, meant to solve problems your customers/business may relate to. Cycle.js and Functional Reactive User Interfaces: In this talk we will discover how Cycle.js is purely reactive and functional, and why it's an interesting alternative to React. Draw Cycle: Simple Cycle.js program visualized Drivers: Drivers are functions that listen to Observable sinks (their input), perform imperative side effects, and may return Observable sources (their output). Animation: A Cycle driver for requestAnimationFrame. Audio Graph Driver: Audio graph driver for Cycle.js based on virtual-audio-graph. Cookie: Cycle.js Cookie Driver, based on cookie_js library. DOM: The standard DOM Driver for Cycle.js based on virtual-dom, and other helpers. Fetch: A Cycle.js Driver for making HTTP requests, using the Fetch API. Fetcher: A Cycle.js Driver for making HTTP requests using stackable-fetcher. Firebase: Thin layer around the firebase javascript API that allows you to query and declaratively update your favorite real-time database. HTTP: A Cycle.js Driver for making HTTP requests, based on superagent. Hammer.js: The driver incorporates the Hammer.js gesture library. History: Cycle.js URL Driver based on the rackt/history library. Keys: A Cycle.js driver for keyboard events. Mongoose.js: A driver for using Mongoose with Cycle JS. Accepts both, write and read operations. Notification: A Cycle.js Driver for showing and responding to HTML5 Notifications. Router: A router built from the ground up with Cycle.js in mind. Stands on the shoulders of battle-tested libraries switch-path for route matching and rackt/history for dealing with the History API. Router5: A source/sink router driver for Cycle.js, based on router5. Server-Sent Events: Cycle.js driver for Server-Sent Events (SSE), a browser feature also known as EventSource. Server-Sent Events allow the server to continuously update the page with new events, without resorting to hacks like long-polling. Snabbdom: Alternative DOM driver utilizing the snabbdom library. Socket.IO: A Cycle driver for applications using Socket.IO Storage: A Cycle.js Driver for using localStorage and sessionStorage in the browser. Example Projects: Example applications built with Cycle.js Cycle.js Examples: Browse and learn from examples of small Cycle.js apps using Core, DOM Driver, HTML Driver, HTTP Driver, JSONP Driver, and others. RX Marbles: Interactive diagrams of Rx Observables. TODO: Minimum Viable Pizza: Minimum Viable Pizza implemented with Cycle.js Tricycle: A scratchpad for trying out Cycle.js. Intro to Functional Reactive Programming with Cycle.js: Nick Johnstone gives an introduction to developing with Cycle.js in this video presentation. Learning How to Ride: an Introduction to Cycle.js: In this talk, Fernando Macias Pereznieto introduces us to the good, the bad, and the beautiful of using Cycle.js, whether you are a complete beginner or an experienced JS ninja. Motorcycle.js: This is a sister project that will continue to evolve and grow alongside Cycle.js for the foreseeable future. The primary focus of this project is to tune it for performance as much as possible. Most: Monadic reactive streams with high performance. Plug and Play All Your Observable Streams With Cycle.js: Frederik Krautwald explains the principles behind Cycle.js, it's inner workings and how to use it to create a simple program with drivers. Tricycle: A scratchpad for trying out Cycle.js. What Developers Need to Know about MVI (Model-View-Intent): The article explains the general MVI pattern and how it relates to React, Reactive Programming and Cycle.js Cycle.js and Functional Reactive User Interfaces: In this talk we will discover how Cycle.js is purely reactive and functional, and why it's an interesting alternative to React. Dynamics of Change: why Reactivity Matters: In this talk we will see when passive or reactive strategy is advantageous, and how the reactive strategy is a sensible default. Enemy of the State: An introduction to Functional Reactive Programming and Bacon.js by Philip Roberts. MobX: MobX is a battle tested library that makes state management simple and scalable by transparently applying functional reactive programming. Promises + FP = Beautiful Streams: Yassine Elouafi show how to use functional programming and algebraic data types to derive a pure functional definition of reactive programming like streams. Stream Libraries: Libraries which help you compose asynchronous operations on streams of time-varying values and events. Bacon.js: A small functional reactive programming lib for JavaScript. Turns your event spaghetti into clean and declarative feng shui bacon, by switching from imperative to functional. Kefir.js: Kefir — is a Reactive Programming library for JavaScript inspired by Bacon.js and RxJS, with focus on high performance and low memory usage. Most: Monadic reactive streams with high performance. Reactive Extensions (RxJS): RxJS is a set of libraries for composing asynchronous and event-based programs using observable sequences and fluent query operators. Async JavaScript with Reactive Extensions: Jafar Husain explains in this video how Netflix uses the Reactive Extensions (Rx) library to build responsive user experiences that strive to be event-driven, scalable and resilient. Exploring Rx Operators: FlatMap: Christoph Burgdorf introduces the FlatMap operator and its usage for collections and observables. Exploring Rx Operators: Map: Christoph Burgdorf explains how to use the map operator in RxJS. Functional Core Reactive Shell: Giovanni Lodi makes an overview of different architecture meta-patterns and describes his current findings about functional programming and observables as a way to control side effects. Learn RX: A series of interactive exercises for learning Microsoft's Reactive Extensions (Rx) Library for Javascript. Learn RxJS: This site focuses on making RxJS concepts approachable, the examples clear and easy to explore, and features references throughout to the best RxJS related material on the web. Real World Observables: Sergi Mansilla writes an FTP client to use it as an example for a real world application based on RxJS. Rx Training Games: Rx Training Games is a coding playground that can be used to learn and practice Reactive Extensions coding grid-based games Rx-Book: A complete book about RxJS v.4.0. RxMarbles: A webapp for experimenting with diagrams of Rx Observables, for learning purposes. RxState: Simple opinionated state management library based on RxJS and Immutable.js Taking Advantage of Observables in Angular 2: Christoph Burgdorf describes the advantages of Observables and how you can use them in Angular 2 context. Transducers with Observable Sequences: A chapter from the RxJS Book describing Transducers. Why We Built Xstream: The authors needed a stream library tailored for Cycle.js. It needs to be “hot” only, small in kB size and it should have only a few and intuitive operators. Xstream: An extremely intuitive, small, and fast functional reactive stream library for JavaScript. Why We Built Xstream: The authors needed a stream library tailored for Cycle.js. It needs to be “hot” only, small in kB size and it should have only a few and intuitive operators. The Introduction to Reactive Programming: André Staltz provides a complete introduction to the Reactive Programming and RxJS. What if the User was a Function?: In this video André Staltz talks about the input/output cycle between humans and computers and how to take advantage of this model by using FRP and event streams. Compatibility Ability of a product to work with different input/output devices and rendering software. Including printers, email, mobile devices and different browsers. Cross Browser: Cross-browser refers to the ability of a website, web application, HTML construct or client-side script to function in environments that provide its required features and to bow out or degrade gracefully when features are absent or lacking. Can I use ... ?: "Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers. Dev Tools by Microsoft: These tools allow you to test your product on different version of Internet Explorer and Microsoft Edge. HTML5 Cross Browser Polyfills: So here we're collecting all the shims, fallbacks, and polyfills in order to implant HTML5 functionality in browsers that don't natively support them. HTML5 Please: Look up HTML5, CSS3, etc features, know if they are ready for use, and if so find out how you should use them – with polyfills, fallbacks or as they are. Modernizr: It's a collection of superfast tests – or “detects” as we like to call them – which run as your web page loads, then you can use the results to tailor the experience to the user. Normalize.css: A modern, HTML5-ready alternative to CSS resets. Polyfill.io: Just the polyfills you need for your site, tailored to each browser. E-Mail: Preparing HTML based electronic mail. Bulletproof E-Mail Buttons: Design gorgeous buttons using progressively enhanced VML and CSS. Email Lab: This a project for developing and testing email templates. It uses Grunt to streamline and simplify the creation of email templates. Email template can be built with re-usable components. Email-Boilerplate: Use these code examples as a guideline for formatting your HTML email to avoid some of the major styling pitfalls in HTML email design. Foundation for Emails 2: Frontend Framework for E-Mails including a grid, global styles, aligment classes, buttons, callout panels, thumbnail styles, typography, visibility classes. MJML: MJML is a markup language designed to reduce the pain of coding a responsive email. Its semantic syntax makes it easy and straightforward and its rich standard components library speeds up your development time and lightens your email codebase. MailChimp E-Mail Blueprints: Email Blueprints is a collection of HTML email templates that can serve as a solid foundation and starting point for the design of emails. Open Source Email Templates: The sendwithus Open Source Template Project is a collection of free email templates created and managed by the sendwithus team and community. Really Simple Responsive HTML Email Template: Sometimes all you want is a really simple HTML email template. Here it is. Responsive Email Design: In this guide, the author will cover the fundamentals of designing and building a mobile-friendly email and back it all up with some neat tips and techniques. Responsive Email Templates: Zurb Studios put together this set of super awesome email templates so that you can make your email campaigns responsive. The Ultimate Guide to CSS: A complete breakdown of the CSS support for the top 10 most popular mobile, web and desktop email clients on the planet. Keyboard: Working with keyboard input in a web browser. What's New with KeyboardEvents? Keys and Codes!: Jeff Posnick talks about the code and key event attributes and how to use them in practice. Mobile: Development of websites optimized for viewing on smartphone and tablet devices. Emulation: Tools for emulating features of mobile devices on a desktop. Responsinator: Quickly test any website in popular resolutions. Simulate Mobile Devices with Chrome Developer Tools: Use Chrome DevTools' Device Mode to build mobile-first, fully responsive web sites. Learn how to use it to simulate a wide range of devices and their capabilities. Touché: Touché: bringing touch events to non-touch browsers (how touching!). No dependencies. No code bloat. thumbs.js: Adds touch support to your browser. Gestures: Resources for working with touch mechanics (what your fingers do on the screen) and touch activities (results of specific gestures). Hammer.js: Hammer helps you add support for touch gestures to your page, and remove the 300ms delay from clicks. Introduction to Gestures: Descriptions of different gestures an their meanings. Pointer Events Polyfill: PEP polyfills pointer events in all browsers that haven't yet implemented them, providing a unified, responsive input model for all devices and input types. Touchy: Touchy is a jQuery plugin for managing touch events on W3C-compliant browsers, such as Mobile Safari or Android Browser, or any browser that supports the ontouchstart, ontouchmove and ontouchend events. jGestures: A jQuery plugin that enables you to add gesture events just like native jQuery events. Includes event substitution for mouse events. Layout: The way in which the parts of the website are arranged or laid out. Snap.js: A Library for creating beautiful mobile shelfs (side menus) in Javascript. Swipe: Swipe is the most accurate touch slider. Swiper: Swiper is a free mobile touch slider with hardware accelerated transitions and native behavior. It is intended to be used in mobile websites, mobile web apps, and mobile native/hybrid apps. jqm-pagination: A jQuery Mobile plugin for sequential pagination between pages with support for touch, mouse, and keyboard. swipeslide: A Zepto Plugin for iOS like swipe navigation. Scrolling: Native scrolling of the browsers doesn't always fit for mobile websites. There are resources which solve this problem. Overscroll: Overscroll is a jQuery plug-in that mimics the iphone/ipad scrolling experience in a browser. Overthrow: A framework-independent, overflow: auto polyfill for use in responsive design. Zynga Scroller: A pure logic component for scrolling/zooming. It is independent of any specific kind of rendering or event system. iScroll: iScroll is a high performance, small footprint, dependency free, multi-platform javascript scroller. jQuery.pep.js: A lightweight plugin for kinetic-drag on mobile/desktop. jSwipeKinetic: A jQuery plugin that enables you to add kinetic scrolling on your touch optimized projects. jSwipeKinetic is build on top of jGestures. pull-to-refresh.js: This plugin enables a pull-to-refresh functionality in mobile safari for scrollable block elements with native scrolling on iOS. Tap Acceleration: Every touch-based mobile browser has an artificial ~300ms delay between you tapping a thing on the screen and the browser considering it a "click", but there are ways to work around this behavior. 300ms Tap Delay, Gone Away: An article by Google describing the 300ms delay and how Chrome 32+ on Anrdoid deals with it. Hammer.js: Hammer helps you add support for touch gestures to your page, and remove the 300ms delay from clicks. Tappable: Tappable is a simple, standalone library to invoke the tap event for touch-friendly web browsers. fastclick: FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a click event on mobile browsers. Touch Keyboard: Almost all modern smartphones provide a touch based keyboard for text input. There are some tactics to influence them and work around their quirks. A Guide To Designing Touch Keyboards: In this article, we will look a bit deeper into the usability issues surrounding touch keyboards, including five design guidelines that will alleviate some of these pains. Working With Sensors: All mobile devices are equipped with sensors like gyroscope, accelerometers, photometers, magnetometers and so on. Some of them are accessible in a browser through JavaScript. This End Up: Using Device Orientation: In this article, we'll take a look at device orientation and motion events, and use CSS to rotate an image based on the orientation of the device. lenticular.js: Tilt-controlled images in the browser. Printers: Manipulation of printer output through CSS. Tips And Tricks For Print Style Sheets: A comprehensive guide for print optimization including background images and colors, expanding external links, QR codes, CSS3 filters for print quality. Responsive Web Design (RWD): RWD responds to the needs of the users and the devices they're using. The layout changes based on the size and capabilities of the device. Data Tables: Tables filled with data don't behave well on small screens. Here are some resources to tame them. Responsive Data Tables: Several ideas by Chris Coyier on how to deal with responsive tables. stacktable.js: jQuery plugin for stacking tables on small screens. Future Friendly Thinking: We want to make things that are future friendly. The following ideas have been on our minds recently. Help us explore them further or suggest new ones. How to make a Responsive Newspaper-like layout: The article describes several approaches for creating multi column websites. Images: Images pose a set of problems on responsive websites: scaling, performance, retina screens and file size. Adaptive Images: Adaptive Images detects your visitor's screen size and automatically creates, caches, and delivers device appropriate re-scaled versions of your web page's embeded HTML images. Choosing A Responsive Image Solution: This article leads you through the basics, and then arms you with the information you'll need to pick the best responsive image solution for your situation. Clown Car Technique: We can use media queries within SVG to serve up the right image. The beauty of the "Clown Car" technique is that all the logic remains in the SVG file. How to Use Responsive Images...: Engineers at Shutterstock describe different problems and solutions around responsive images. Picturefill: A responsive image polyfill for , srcset, sizes, and more. Riloadr: The goal of this library is to deliver optimized, contextual image sizes in responsive layouts that utilize dramatically different image sizes at different resolutions in order to improve page load time. Why We Need Responsive Images: Tim Kadlec talks about page weight and responsive image solutions. imgLiquid: A jQuery Plugin to resize images to fit in a container. jQuery Picture: jQuery Picture is a tiny (2kb) plugin to add support for responsive images to your layouts. It supports both figure elements with some custom data attributes and the new proposed picture format. Monitoring Breakpoints: Triggering JavaScript events on different breakpoints. Breakpoints.js: Define breakpoints for your responsive design, and Breakpoints.js will fire custom events when the browser enters and/or exits that breakpoint. Harvey: Harvey helps you monitor and manage behavior changes by firing an event whenever your media query is activated. enquire.js: enquire.js is a lightweight, pure javascript library (with no dependencies) for programmatically responding to media queries. Navigation: Adapting the website navigation to different screen sizes. Complex Navigation Patterns: The article describes some emerging patterns for dealing with complex, lengthy and/or multi-level navigations. Responsive Navigation On Complex Websites: To illustrate the techniques involved in implementing responsive navigation on a large website, author refers to two actual clients. Responsive Navigation Patterns: The article describes some of the more popular techniques for handling navigation in responsive designs. Responsive Design Workflow: In this video, Stephen Hay explores at a content-based approach to design workflow which is grounded in our multiplatform reality, not fixed-width Photoshop comps and overproduced wireframes. Responsive Elements: Responsive elements makes it possible for any element to adapt and respond to the area they occupy. It's a tiny JavaScript library that you can drop into your projects today. Responsive Patterns: A collection of patterns and modules for responsive designs. Text: Working with text in a context of different viewport sizes. FitText: FitText makes font-sizes flexible. Use this plugin on your fluid or responsive layout to achieve scalable headlines that fill the width of a parent element. Out Of Words!: The responsive typography framework behind Words App. Responsive Font Sizing: Making your font size respond to your screen size, easy & maintainable. Responsive Measure: A jQuery plugin for generating a responsive ideal measure. Truly Fluid Typography With vh And vw Units: This article describes viewport units and other technics to achieve typography which resizes smoothly with the screen. Viewport Component: Viewport is a component to ease viewport management. You can get the dimensions of the viewport and beyond, which can be quite helpful to perform some checks with JavaScript. Web Accessibility: Web accessibility means that people with disabilities can perceive, understand, navigate, and interact with the Web, and that they can contribute to the Web. Notes on Using ARIA in HTML: This document is a practical guide for developers on how to add accessibility information to HTML elements using the Accessible Rich Internet Applications specification. The A11Y Project: A community-driven effort to make web accessibility easier. Ecosystem Important developers, companies, organizations and news sources. Communities Around Projects: Successful open source projects attract many developers who produce plugins, libraries, tutorials and other resources. This section collects such resources. Angular: AngularJS is a web application framework trying to address many of the challenges encountered in developing single-page applications. Adventures in Angular: Adventures in Angular is a weekly podcast dedicated to the Angular JavaScript framework and related technologies, tools, languages, and practices. Angular 2 ESNext Starter: This repo stands as a starting point for those who try Angular 2 in Javascript. It shows techniques how easy development can be also without Typescript. Angular 2 Template Syntax: Victor Savkin writes about Angular 2 Templates including bindings, interpolation, syntax sugar, web component support and much more. Angular 2 Upgrade Strategies from Angular 1.x: Some thoughts on general upgrading to Angular 2 and what you/your team can do to prepare. Building Redux in TypeScript with Angular 2: In this post we're going to discuss the ideas behind Redux. How to build our own mini version of the Redux Store and hook it up to Angular 2. Change Detection in Angular 2: In this article Victor Savkin talks in depth about the Angular 2 change detection system. How to Implement Conditional Validation in Model-driven Forms: In this article, we will learn about how to handle conditional validation in our model-driven form using the latest forms module. How to Prevent Name Collisions in Angular 2 Providers: Opaque tokens are distinguishable and prevent us from running into naming collisions. Whenever we create a token that is not a type, OpaqueToken should be used. Ng-Newsletter: The free, weekly newsletter of the best AngularJS content on the web. PrimeNG: PrimeNG is a collection of rich UI components for AngularJS2. PrimeNG is a sibling of the popular JavaServer Faces Component Suite, PrimeFaces. Simple Language Translation: Create a pipe that we can use to translate words in the HTML view and a service that we can use to translate our words in JS / Typescript. Using Model-Driven Forms with FormGroup and FormControl: In this article, we will learn about building model-driven form with validation using the latest forms module, then we will talk about what are the advantages / disadvantages of using model driven form as compared to template-driven form. Backbone.js: Backbone supplies structure to JavaScript-heavy applications by providing models, collections, views with declarative event handling, and connects it all to your existing application over a RESTful JSON interface. Bootstrap: Bootstrap is a HTML, CSS, and JS framework for developing responsive, mobile first projects on the web. Bootstrap 4 Cheat Sheet: A quick reference for Bootstrap v4 by Alexander Rechsteiner. Tree Shaking Bootstrap: Jacob Parker describes how to include only those parts of Bootstrap you are really using on your website by leveraging CSS modules and ES6 modules. Cycle.js: A functional and reactive JavaScript framework that solves the cyclic dependency of Observables which emerge during dialogues (mutual observations) between the Human and the Computer. Async Driver: Higher order factory for creating cycle.js async request based drivers. Allows you almost completely eliminate boilerplate code for this kind of drivers. Cycle.js Was Built to Solve Problems: In this video André Staltz shows how Cycle.js has a practical purpose, meant to solve problems your customers/business may relate to. Cycle.js and Functional Reactive User Interfaces: In this talk we will discover how Cycle.js is purely reactive and functional, and why it's an interesting alternative to React. Draw Cycle: Simple Cycle.js program visualized Drivers: Drivers are functions that listen to Observable sinks (their input), perform imperative side effects, and may return Observable sources (their output). Animation: A Cycle driver for requestAnimationFrame. Audio Graph Driver: Audio graph driver for Cycle.js based on virtual-audio-graph. Cookie: Cycle.js Cookie Driver, based on cookie_js library. DOM: The standard DOM Driver for Cycle.js based on virtual-dom, and other helpers. Fetch: A Cycle.js Driver for making HTTP requests, using the Fetch API. Fetcher: A Cycle.js Driver for making HTTP requests using stackable-fetcher. Firebase: Thin layer around the firebase javascript API that allows you to query and declaratively update your favorite real-time database. HTTP: A Cycle.js Driver for making HTTP requests, based on superagent. Hammer.js: The driver incorporates the Hammer.js gesture library. History: Cycle.js URL Driver based on the rackt/history library. Keys: A Cycle.js driver for keyboard events. Mongoose.js: A driver for using Mongoose with Cycle JS. Accepts both, write and read operations. Notification: A Cycle.js Driver for showing and responding to HTML5 Notifications. Router: A router built from the ground up with Cycle.js in mind. Stands on the shoulders of battle-tested libraries switch-path for route matching and rackt/history for dealing with the History API. Router5: A source/sink router driver for Cycle.js, based on router5. Server-Sent Events: Cycle.js driver for Server-Sent Events (SSE), a browser feature also known as EventSource. Server-Sent Events allow the server to continuously update the page with new events, without resorting to hacks like long-polling. Snabbdom: Alternative DOM driver utilizing the snabbdom library. Socket.IO: A Cycle driver for applications using Socket.IO Storage: A Cycle.js Driver for using localStorage and sessionStorage in the browser. Example Projects: Example applications built with Cycle.js Cycle.js Examples: Browse and learn from examples of small Cycle.js apps using Core, DOM Driver, HTML Driver, HTTP Driver, JSONP Driver, and others. RX Marbles: Interactive diagrams of Rx Observables. TODO: Minimum Viable Pizza: Minimum Viable Pizza implemented with Cycle.js Tricycle: A scratchpad for trying out Cycle.js. Intro to Functional Reactive Programming with Cycle.js: Nick Johnstone gives an introduction to developing with Cycle.js in this video presentation. Learning How to Ride: an Introduction to Cycle.js: In this talk, Fernando Macias Pereznieto introduces us to the good, the bad, and the beautiful of using Cycle.js, whether you are a complete beginner or an experienced JS ninja. Motorcycle.js: This is a sister project that will continue to evolve and grow alongside Cycle.js for the foreseeable future. The primary focus of this project is to tune it for performance as much as possible. Most: Monadic reactive streams with high performance. Plug and Play All Your Observable Streams With Cycle.js: Frederik Krautwald explains the principles behind Cycle.js, it's inner workings and how to use it to create a simple program with drivers. Tricycle: A scratchpad for trying out Cycle.js. What Developers Need to Know about MVI (Model-View-Intent): The article explains the general MVI pattern and how it relates to React, Reactive Programming and Cycle.js Dojo Toolkit: A JavaScript toolkit that saves you time and scales with your development process. Provides everything you need to build a Web app. Language utilities, UI components, and more, all in one place, designed to work together perfectly. Ember: Ember.js is an open-source JavaScript web framework, based on the MVC pattern. It allows developers to create scalable single-page web applications. Bindings in Ember: Unlike most other frameworks that include some sort of binding implementation, bindings in Ember.js can be used with any object. Router.js (Ember): Router.js is the routing microlib used by Ember.js. Foundation: Foundation provides a responsive grid and HTML and CSS UI components, templates, and code snippets, including typography, forms, buttons, navigation and other interface components, as well as optional JavaScript extensions. Gulp: Gulp is a toolkit that helps you automate painful or time-consuming tasks in your development workflow. It's very fast, platform-agnostic and simple. Articles & Tutorials: Publications about gulp or step by step guides for setting up and using gulp in a project. Building with Gulp 3 and 4 (Series): Great series of articles about single components and gulp as a whole. Part 1: Examples: Introduction to gulp and gulpfile.js. Part 2: Gulp's anatomy: Orchestrator, Undertaker, Vinyl and Vinyl FS, Gulp Plugins. Part 3: Writing transformers: Using map-stream, though2 and event-stream. Part 4: Incremental builds: Building files which changed since last run and caching. Part 5: Caveats: Error management in Gulp 3 and "MANY:1 disguised as a 1:1" problem. The vision, history, and future of the project (Apr. 2014): The article talks about Streams, Vinyl, Vinyl Adapters, Orchestrator and Error Management in Gulp 4. Why Gulp might not be the Answer: ... there is still a conceptual problem that Gulp has yet to address. Many build steps are not 1:1 (one file in, one file out) but rather n:1 or 1:n. CSS: Gulp plugins for working with CSS files. gulp-clean-css: gulp plugin to minify CSS, using clean-css. gulp-cssnano: Minify CSS with cssnano. Concatenation: Plugins for file concatenation. For example bundling CSS or JavaScript files. gulp-concat: This plugin will concat files by your operating systems newLine. It will take the base directory from the first file that passes through it. gulp-group-concat: Concats groups of files into a smaller number of files Deployment: Plugins for pushing built files into production. gulp-tar: Create tarball from files. vinyl-ftp: Blazing fast vinyl adapter for FTP. vinyl-s3: Use S3 as a source or destination of vinyl files. Ecosystem: The network of developers and plugins around gulp.@sindresorhus plugins: A collection of plugins by Sindre Sorhus. Gulp Friendly NPM Packages: Normal node packages that work with gulp. Filters: Plugins for filtering files in a vinyl stream. gulp-cache: A temp file based caching proxy task for gulp. gulp-cached: A simple in-memory file cache for gulp. gulp-changed: Only pass through changed files. gulp-filter: Filter files in a vinyl stream. gulp-newer: Pass through newer source files only. gulp-remember: A plugin for gulp that remembers and recalls files passed through it. vinyl-diff: This library allows you to perform diffs between streams of vinyl. Images: Plugins for working with images. gulp-imagemin: Minify PNG, JPEG, GIF and SVG images. gulp-webp: Convert PNG, JPEG, TIFF images to WebP. JavaScript: Module loaders, minifiers and other tools for working with JavaScript files. gulp-pure-cjs: Gulp plugin for Pure CommonJS builder. gulp-uglify: Minify files with UglifyJS. yoloader: A CommonJS module loader implementation. It provides tools to bundle a CommonJS based project and to load such bundles. SourceMaps: A source map provides a way of mapping code within a compressed file back to it's original position in a source file. Plugins with gulp sourcemaps support: A list of plugins which support gulp-sourcemaps. gulp-sourcemaps: Source map support for Gulp.js vinyl-sourcemaps-apply: Apply a source map to a vinyl file, merging it with preexisting source maps. Utility: Tools and parts for building gulp plugins. gulp-count: Count files in a vinyl stream. gulp-debug: Debug vinyl file streams to see what files are run through your gulp pipeline. gulp-size: Logs out the total size of files in the stream and optionally the individual file-sizes. lazypipe: Lazypipe allows you to create an immutable, lazily-initialized pipeline. It's designed to be used in an environment where you want to reuse partial pipelines, such as with gulp. map-stream: Create a through stream from an asyncronous function. Vinyl: Vinyl is a very simple metadata object that describes a file. gulp-chmod: Change permissions of Vinyl files. gulp-rename: A plugin to rename files easily. mem-fs: Simple in-memory vinyl file store. vinyl-ast: Parse-once and generate-once AST tool bridge for Gulp plugins. vinyl-buffer: Creates a transform stream that takes vinyl files as input, and outputs buffered (isStream() === false) vinyl files as output. vinyl-file: Create a vinyl file from an actual file. vinyl-fs: Vinyl adapter for the file system. vinyl-fs-fake: A vinyl adapter that extends vinyl-fs to allow for easy debugging by passing in virtual files instead of globs, and calling a function instead of writing. vinyl-git: Vinyl adapter for git. vinyl-map: Map vinyl files' contents as strings, so you can easily use existing code without needing yet another gulp plugin! vinyl-paths: Get the file paths in a vinyl stream. vinyl-source-buffer: Convert a text stream into a vinyl pipeline whose content is a buffer. vinyl-source-stream: Use conventional text streams at the start of your gulp or vinyl pipelines, making for nicer interoperability with the existing npm stream. vinyl-to-stream: Convert a vinyl stream to a text stream. vinyl-transform: Wraps standard text transform streams so you can write fewer gulp plugins. Fulfills a similar use case to vinyl-map and vinyl-source-stream. Meteor: Meteor is a full-stack JavaScript platform for developing modern web and mobile applications. Meteor includes a key set of technologies for building connected-client reactive applications, a build tool, and a curated set of packages. React: React is a JavaScript library for creating user interfaces. Many people choose to think of React as the V in MVC. We built React to solve one problem: building large applications with data that changes over time. 3 Lightweight React Alternatives: Dan Prince explores Preact, VirtualDom & Deku. A Stateless React App?: James K Nelson describes how to avoid state in React Components. Block, Element, Modifying Your JavaScript Components: Mark Dalgleish is discussing how to organize React code with BEM and build everything with Webpack. CSS Modules To The Rescue.jsx: If you use react-like templates/components, use webpack CSS loader to enable CSS Modules and forget about global CSS problems.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Awesome Static Site Resources Awesome Static Site Resources Table of Contents Audio Books Calendar and Scheduling Images Maps Presentations Video Code Functions as a Service FaaS GraphQL Community Comments Forms Live Chat Newsletters Social Media Surveys E-Commerce Payments Search Analytics Authentication Other Related Lists Audio SoundCloud - Audio hosting with an embeddable player. Up to 3 hours of content is free. Mixcloud - Audio hosting with unlimited uploads and an embeddable player. Spotify - You can embed any song, album, or playlist with a Spotify Play Button. Books Google Books - Allows you to display the books in your Google Books Library. Goodreads API and widgets - Allows you to access any of the Goodreads data. Widgets are found on the widgets tab on your settings page. Calendar and Scheduling Google Calendar - Embeddable calendar that you can collaborate with other people. Booking.js - Beautiful embeddable booking widget. zenplanner - Paid - Online scheduling for fitness. Images Flickr - Online photo hosting by Yahoo. Cloudinary - Image hosting, manipulation and delivery. Maps Google Maps - Google maps are easily embeddable. Mapbox - Really nice looking embeddable maps. Presentations Prezi - Online presentations with really transitions that can zoom and rotate. Reveal.js - HTML presentation framework. Slides.com - A place for creating, presenting and sharing slide decks. SpeakerDeck - Upload your slides as a PDF, and get an online, shareable presentation. Video Mux - Paid - An API to play videos directly to the client. Can also power live streams. YouTube - Embeddable videos with unlimited uploads. Vimeo - Paid - Embeddable videos with no ads. Vevo - Embeddable music videos. Wistia - Free plan has a limit of 25 videos. Code Codepen - A playground of embeddable front-end code examples. JS Bin - Embeddable front-end code examples. JSFiddle - Embeddable front-end code examples. highlight.js - Syntax highlighting for the web. Functions as a Service 1Backend - Deploy your backend in seconds. Free tier included. Open source. AWS Lambda - AWS Lambda lets you run code without provisioning or managing servers. You pay only for the compute time you consume Google Cloud Functions - Create single-purpose, stand-alone functions that respond to Cloud events without the need to manage a server or runtime environment Webtask by Auth0 - Call code on the server with simple HTTP, easier to set up by far than Lambda or Google's Azure Functions - by Microsoft - same premise as Lambda on the Azure cloud IronWorkers - by Iron.io - Run code in a multilanguage containerized environment with unlimited scale and simple pricing IronFunctions - by Iron.io - IronFunctions is an open source serverless computing platform for any cloud - private, public, or hybrid. OpenWhisk by IBM - part of their BlueMix hosting platform, and open source, ties into their Watson AI ecosystem nicely StackPath EdgeEngine - Write functions as a service in the language of your choice and deploy them to a global network of data centers. All the networking, including intelligent routing and load balancing, is managed by StackPath over a private backbone. Vercel - Vercel lets people write functions as a service in their language of choice and deploy as part of a monorepo. Azure Static Web Apps - Full-stack static app hosting including serverless Functions, authentication, CDN and more GraphQL FaunaDB - Serverless GraphQL database. Free tier with no time limit. Easily included in Netlify apps. Community Comments Staticman - Staticman is a Node.js application that receives user-generated content and uploads it as data files to a GitHub repository. In practice, this allows you to have dynamic content (e.g. blog post comments) as part of a fully static website, as long as your site automatically deploys on every push to GitHub, as seen on GitHub Pages, Netlify and others. Disqus - Easily embeddable comments with nested replies, multiple login methods, and email notifications. Facebook Comments - Embeddable comments for your site by Facebook. IntenseDebate Comments - Embeddable comments with nested replies, multiple login methods, and email notifications. LiveFyre - Real-time comments, SEO-optimized, stocked with social features, and beautiful on both desktop and mobile. Redditjs Embed Widget - Embed Reddit comments on your site. If it hasn't been posted, it will show a link to encourage the user to submit. Muut.com - Embeddable comments, forum and private messaging. A lot of functionality, but really low footprint left on your website. Gitment - Comment system based on GitHub Issues, which can be used in the frontend without any server-side implementation. giscus - A comments widget built on GitHub Discussions. Forms Really Simple Forms Formspree - Receive emails from a form on your static website. elFormo - Simple form processing and response retrieval via email. Flipmail - Simple form processing and response retrieval via email. MailThis - Simple form submissions via email with optional attachments. Simple Form - Simple forms with optional file attachments, email notifications, and online submission viewing. Brisk Forms - Free form submission service emails you responses while keeping your email address private and is open source. 99 Inbound - Form endpoint service with email/Slack notifications and third party app integrations (e.g. MailChimp) Getform - Form backend platform for designers and developers, with email and integrations. Form.taxi - Backend to handle form submissions easily and reliably, with email notifications, file uploads and GDPR-compliant data processing. Normal Forms Formcarry - Hassle-free HTML form endpoints for your form, powerful dashboard, reliable spam blocking, attachment uploads and Zapier integrations. Formcake - The form backend built for developers: Zapier integrations, simple endpoint API, unlimited forms. Google Forms - Saves results into Google Sheets and can email you when there is a submission. FormKeep - Paid - View form submissions in a beautiful web interface. It has spam filtering and it integrates with webhooks such as Gmail, Trello, and Basecamp. 123 Contact Form - Connects to other online services such at MailChimp, Salesforce, and Google Drive. It also integrates with payment Processers and includes security and analytics. FormAssembly - Allows you to build any kind of form that can include complex branching logic and multiple pages. FormSite - Form builder with payments and form management. FormStack - Forms with A/B testing, partial submission, analytics, and integrations. Sheetsu - POST and GET your data to Google Spreadsheet. Typeform - Awesome forms that can be embedded. Wufoo - Free or Paid - Forms that you can build with a form designer, with notifications, reports, and payments. Zoho - Forms with file upload and captcha. GitHub Issues - This is an interesting way for developers to get comments/questions. See github.com/sindresorhus/ama for an example. Utterences - A lightweight comments widget built on GitHub issues. FormBackend - Create form-backends and submit your HTML forms to our backend. View the entries online and connect to other services. Receive an email every time a new entry is submitted. Pageclip - A flexible server / backend for HTML forms. View your data in the realtime web interface, or use the API to get CSV and JSON output. Formester - Forms and email marketing (lead collection, email campaigns, and newsletters) with integrations. StaticKit - Modern forms for static sites, with native support for React. SheetDB - Turn a Google Spreadsheet into a JSON API. Provided by the Host Netlify - Netlify comes with built-in form handling. Live Chat jivochat - JivoSite is a professional live chat for websites that was specifically designed to increase your online sales. LiveChat - Live chat on your website. Olark - Live chat on your website. You can also see who's on your website and what they're doing. SnapEngage - Live chat with integrations and custom styles. tawk.co - Lets you monitor and chat with visitors on your website. WebsiteAlive - Live chat for your website & social networks. Zopim - Live chat with free trial. Newsletters MailChimp - Free email marketing. You can pay to add more features. Constant Contact - Email marketing with campaigns, autoresponders, and analytics. AWeber - Email marketing with campaigns, autoresponders, and analytics. Campaign Monitor - Email marketing with campaigns, autoresponders, and analytics. MailerLite - Free email marketing. You can pay for more subscribers. Social Media Pinterest - Pin It Button. Twitter - Embedded tweets. Facebook - Facebook embedded plugins. ShareThis - Sharing buttons for multiple social networks. Kontaktify - A contact widget that provides an easy way for visitors to get in touch. Surveys Google Forms - You can use Google forms for surveys or for forms on your site. SurveyMonkey - Easy to use and free surveys. Typeform - Really beautiful forms. Qualaroo - Embed surveys anywhere on your website that comes up from the bottom right side of the screen. Insight Stash - Fast, Simple survey forms. E-Commerce Ecwid - Embeddable shopping cart. FoxyCart - Add a shopping cart with basic html code. Snipcart - Include a few lines of code for a full online shop. Gumroad - An all-in-one solution to sell your work. Payhip - An embeddable way to sell digital downloads & memberships Moltin - Add eCommerce functionality to anything. Trolley - Add a popup cart to any website - designed for static & JAMstack sites. Commerce Layer - Add enterprise ecommerce to your JAMstack. Payments MoneyButton - Website payments and donations using Bitcoin (Satoshi's Vision). ShapeShift Shifty Button - Accept payments using various cryptocurrencies. Search Self-hosted: lunr.js - Simple full-text search in your browser. itemsjs - Full text, faceted, almost dependency free search engine in javascript minisearch - Tiny and powerful JavaScript full-text search engine for browser and Node flexsearch - Next-Generation full text search library for Browser and Node.js fuse.js - Powerful, lightweight fuzzy-search library, with zero dependencies static-search - A Go program to generate JSON index of HTML files, and a JavaScript component with optional UI to search this index elasticlunr - Lightweight full-text search engine developed in JavaScript for browser search and offline search based on Lunr.js tinysearch - Tiny, full-text search engine for static websites built with Rust and Wasm js-search - Client-side searches of JavaScript and JSON objects, ES5 compatible and does not require jQuery or any other third-party libraries search-index - A persistent, network resilient, full text search library for the browser and Node.js fuzzysearch - Tiny and blazing-fast fuzzy search in JavaScript fuzzy - Fuzzy search / filter for browser and node fullproof - Javascript library that provides high-quality full-text search in the browser Jets.js - Native CSS search engine Third party integration: Google Custom Search Engine - Search your site with a custom Google Search. Algolia - Hosted Search API that delivers instant and relevant results from the first keystroke. CloudSh - Powerful search for your website with a few lines of JavaScript. Analytics Google Analytics - Freemium web analytics service offered by Google. Simple Analytics - 💲 - Simple, clean, and friendly analytics. Authentication Uthentic - Serverless, passwordless login for static sites in 2 lines of code. Other Sketch Fab - Embeddable 3D content. Related Lists Awesome Static Hosting Awesome Azure Static Web Apps
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Awesome Lists Awesome Lists: sindresorhus/awesome-nodejs bcoe/awesome-cross-platform-nodejs dypsilon/frontend-dev-bookmarks vsouza/awesome-ios JStumpp/awesome-android weblancaster/awesome-IoT-hybrid sindresorhus/awesome-electron busterc/awesome-cordova jondot/awesome-react-native XamSome/awesome-xamarin inputsh/awesome-linux Friz-zy/awesome-linux-containers zoidbergwill/awesome-ebpf PandaFoss/Awesome-Arch iCHAIT/awesome-macOS herrbischoff/awesome-macos-command-line agarrharr/awesome-macos-screensavers jaywcjlove/awesome-mac serhii-londar/open-source-mac-os-apps yenchenlin/awesome-watchos deephacks/awesome-jvm mailtoharshit/awesome-salesforce donnemartin/awesome-aws Awesome-Windows/Awesome ipfs/awesome-ipfs fuse-compound/awesome-fuse ianstormtaylor/awesome-heroku thibmaek/awesome-raspberry-pi JesseTG/awesome-qt fregante/Awesome-WebExtensions motion-open-source/awesome-rubymotion vitalets/awesome-smart-tv Kazhnuz/awesome-gnome francoism90/awesome-kde quozd/awesome-dotnet thangchung/awesome-dotnet-core ironcev/awesome-roslyn miguelmota/awesome-amazon-alexa jonleibowitz/awesome-digitalocean Solido/awesome-flutter frenck/awesome-home-assistant victorshinya/awesome-ibmcloud jthegedus/awesome-firebase fkromer/awesome-ros2 adafruit/awesome-adafruitio irazasyed/awesome-cloudflare ravirupareliya/awesome-actions-on-google agucova/awesome-esp denolib/awesome-deno balintkissdev/awesome-dos nix-community/awesome-nix sorrycc/awesome-javascript wbinnssmith/awesome-promises standard/awesome-standard bolshchikov/js-must-watch loverajoel/jstips Kikobeats/awesome-network-js parro-it/awesome-micro-npm-packages feross/awesome-mad-science maxogden/maintenance-modules sindresorhus/awesome-npm avajs/awesome-ava dustinspecker/awesome-eslint stoeffel/awesome-fp-js sindresorhus/awesome-observables RyanZim/awesome-npm-scripts 30-seconds/30-seconds-of-code Richienb/awesome-ponyfills matteocrippa/awesome-swift hsavit1/Awesome-Swift-Education uraimo/Awesome-Swift-Playgrounds vinta/awesome-python timofurrer/awesome-asyncio faroit/awesome-python-scientific-audio adafruit/awesome-circuitpython krzjoa/awesome-python-data-science typeddjango/awesome-python-typing mcauser/awesome-micropython rust-unofficial/awesome-rust krispo/awesome-haskell passy/awesome-purescript avelino/awesome-go lauris/awesome-scala tindzk/awesome-scala-native markets/awesome-ruby razum2um/awesome-clojure hantuzun/awesome-clojurescript h4cc/awesome-elixir sporto/awesome-elm drobakowski/awesome-erlang svaksha/Julia.jl LewisJEllis/awesome-lua inputsh/awesome-c fffaraz/awesome-cpp qinwf/awesome-R iamericfletcher/awesome-r-learning-resources dlang-community/awesome-d CodyReichert/awesome-cl GustavBertram/awesome-common-lisp-learning hachiojipm/awesome-perl kdabir/awesome-groovy yissachar/awesome-dart akullpp/awesome-java eleventigers/awesome-rxjava KotlinBy/awesome-kotlin ocaml-community/awesome-ocaml seancoyne/awesome-coldfusion rabbiabram/awesome-fortran ziadoz/awesome-php jakoch/awesome-composer Fr0sT-Brutal/awesome-pascal ahkscript/awesome-AutoHotkey J2TeaM/awesome-AutoIt veelenga/awesome-crystal sfischer13/awesome-frege onqtam/awesome-cmake robinrodricks/awesome-actionscript3 sfischer13/awesome-eta joaomilho/awesome-idris ohenley/awesome-ada ebraminio/awesome-qsharp koolamusic/awesome-imba desiderantes/awesome-vala coq-community/awesome-coq vlang/awesome-v addyosmani/es6-tools davidsonfellipe/awesome-wpo lvwzhen/tools awesome-css-group/awesome-css addyosmani/critical-path-css-tools davidtheclark/scalable-css-reading-list AllThingsSmitty/must-watch-css AllThingsSmitty/css-protips troxler/awesome-css-frameworks enaqx/awesome-react expede/awesome-relay glauberfc/awesome-react-hooks mateusortiz/webcomponents-the-right-way Granze/awesome-polymer PatrickJS/awesome-angular sadcitizen/awesome-backbone diegocard/awesome-html5 willianjusten/awesome-svg raphamorim/awesome-canvas dnbard/awesome-knockout petk/awesome-dojo NoahBuscher/Inspire ember-community-russia/awesome-ember wasabeef/awesome-android-ui cjwirth/awesome-ios-ui Urigo/awesome-meteor sturobson/BEM-resources afonsopacifer/awesome-flexbox deanhume/typography brunopulis/awesome-a11y sachin1092/awesome-material wbkd/awesome-d3 jonathandion/awesome-emails petk/awesome-jquery AllThingsSmitty/jquery-tips-everyone-should-know notthetup/awesome-webaudio pazguille/offline-first agarrharr/awesome-static-website-services cyclejs-community/awesome-cyclejs dok/awesome-text-editing fliptheweb/motion-ui-design vuejs/awesome-vue sadcitizen/awesome-marionette aurelia-contrib/awesome-aurelia zingchart/awesome-charting candelibas/awesome-ionic ChromeDevTools/awesome-chrome-devtools jdrgomes/awesome-postcss nikgraf/awesome-draft-js TalAter/awesome-service-workers TalAter/awesome-progressive-web-apps choojs/awesome-choo brillout/awesome-redux webpack-contrib/awesome-webpack browserify/awesome-browserify Famolus/awesome-sass websemantics/awesome-ant-design LucasBassetti/awesome-less sjfricke/awesome-webgl preactjs/awesome-preact jbmoelker/progressive-enhancement-resources unicodeveloper/awesome-nextjs web-padawan/awesome-lit-html automata/awesome-jamstack henrikwirth/awesome-wordpress-gatsby myshov/awesome-mobile-web-development lauthieb/awesome-storybook AdrienTorris/awesome-blazor csabapalfi/awesome-pagespeed-metrics aniftyco/awesome-tailwindcss seed-rs/awesome-seed-rs pajaydev/awesome-web-performance-budget sergey-pimenov/awesome-web-animation jetli/awesome-yew nadunindunil/awesome-material-ui componently-com/awesome-building-blocks-for-web-apps TheComputerM/awesome-svelte klaufel/awesome-design-systems innocenzi/awesome-inertiajs mdbootstrap/awesome-mdbootstrap mjhea0/awesome-flask veggiemonk/awesome-docker iJackUA/awesome-vagrant uralbash/awesome-pyramid PerfectCarl/awesome-play1 friendsofcake/awesome-cakephp sitepoint-editors/awesome-symfony pehapkari/awesome-symfony-education chiraggude/awesome-laravel fukuball/Awesome-Laravel-Education blade-ui-kit/awesome-tall-stack gramantin/awesome-rails hothero/awesome-rails-gem phalcon/awesome-phalcon phanan/htaccess fcambus/nginx-resources stve/awesome-dropwizard ramitsurana/awesome-kubernetes unicodeveloper/awesome-lumen pmuens/awesome-serverless PhantomYdn/awesome-wicket vert-x3/vertx-awesome shuaibiyy/awesome-terraform Cellane/awesome-vapor ucg8j/awesome-dash mjhea0/awesome-fastapi kolomied/awesome-cdk kdeldycke/awesome-iam prakhar1989/awesome-courses academic/awesome-datascience siboehm/awesome-learn-datascience josephmisiti/awesome-machine-learning ujjwalkarn/Machine-Learning-Tutorials arbox/machine-learning-with-ruby likedan/Awesome-CoreML-Models h2oai/awesome-h2o SE-ML/awesome-seml georgezouq/awesome-ai-in-finance n2cholas/awesome-jax altamiracorp/awesome-xai edobashira/speech-language-processing dav009/awesome-spanish-nlp arbox/nlp-with-ruby seriousran/awesome-qa tokenmill/awesome-nlg theimpossibleastronaut/awesome-linguistics sobolevn/awesome-cryptography pFarb/awesome-crypto-papers jbhuang0604/awesome-computer-vision ChristosChristofidis/awesome-deep-learning jtoy/awesome-tensorflow aaronhma/awesome-tensorflow-js margaretmz/awesome-tensorflow-lite terryum/awesome-deep-learning-papers guillaume-chevalier/awesome-deep-learning-resources kjw0612/awesome-deep-vision ossu/computer-science lucasviola/awesome-functional-programming dspinellis/awesome-msr analysis-tools-dev/static-analysis harpribot/awesome-information-retrieval desireevl/awesome-quantum-computing mostafatouny/awesome-theoretical-computer-science onurakpolat/awesome-bigdata awesomedata/awesome-public-datasets youngwookim/awesome-hadoop igorbarinov/awesome-data-engineering manuzhang/awesome-streaming awesome-spark/awesome-spark ambster-public/awesome-qlik sduff/awesome-splunk papers-we-love/papers-we-love JanVanRyswyck/awesome-talks tayllan/awesome-algorithms gaerae/awesome-algorithms-education enjalot/algovis owainlewis/awesome-artificial-intelligence marcobiedermann/search-engine-optimization lnishan/awesome-competitive-programming rossant/awesome-math passy/awesome-recursion-schemes EbookFoundation/free-programming-books dariubs/GoBooks RomanTsegelskyi/rbooks hackerkid/Mind-Expanding-Books TalAter/awesome-book-authoring sger/ElixirBooks dreikanter/sublime-bookmarks mhinz/vim-galore emacs-tw/awesome-emacs mehcode/awesome-atom viatsko/awesome-vscode ellisonleao/magictools hzoo/awesome-gametalks godotengine/awesome-godot leereilly/games RyanNielson/awesome-unity hkirat/awesome-chess love2d-community/awesome-love2d pico-8/awesome-PICO-8 gbdev/awesome-gbdev WebCreationClub/awesome-construct stetso/awesome-gideros bs-community/awesome-minecraft leomaurodesenv/game-datasets Dvergar/awesome-haxe-gamedev rafaskb/awesome-libgdx playcanvas/awesome-playcanvas radek-sprta/awesome-game-remakes flame-engine/awesome-flame mhxion/awesome-discord-communities tobiasvl/awesome-chip-8 michelpereira/awesome-games-of-coding sindresorhus/quick-look-plugins jondot/awesome-devenv webpro/awesome-dotfiles alebcay/awesome-shell jorgebucaran/awsm.fish agarrharr/awesome-cli-apps unixorn/awesome-zsh-plugins phillipadsmith/awesome-github stefanbuck/awesome-browser-extensions-for-github tiimgreen/github-cheat-sheet matchai/awesome-pinned-gists arslanbilal/git-cheat-sheet git-tips/tips stevemao/awesome-git-addons compscilauren/awesome-git-hooks moul/awesome-ssh tvvocold/FOSS-for-Dev bnb/awesome-hyper janikvonrotz/awesome-powershell alfred-workflows/awesome-alfred-workflows k4m4/terminals-are-sexy sdras/awesome-actions sindresorhus/awesome-scifi RichardLitt/awesome-fantasy ayr-ton/awesome-geek-podcasts zudochkin/awesome-newsletters victorlaerte/awesome-it-quotes numetriclabz/awesome-db shlomi-noach/awesome-mysql dahlia/awesome-sqlalchemy mark-rushakoff/awesome-influxdb neueda/awesome-neo4j ramnes/awesome-mongodb d3viant0ne/awesome-rethinkdb mohataher/awesome-tinkerpop dhamaniasad/awesome-postgres quangv/awesome-couchdb rayokota/awesome-hbase erictleung/awesome-nosql-guides chrislatorres/awesome-contexture mgramin/awesome-db-tools vaticle/typedb-awesome Anant/awesome-cassandra shime/creative-commons-media brabadu/awesome-fonts chrissimpkins/codeface neutraltone/awesome-stock-resources davisonio/awesome-gif ciconia/awesome-music 44bits/awesome-opensource-documents willianjusten/awesome-audio-visualization ebu/awesome-broadcasting Siilwyn/awesome-pixel-art transitive-bullshit/awesome-ffmpeg notlmn/awesome-icons stingalleman/awesome-audiovisual mfkl/awesome-vlc therebelrobot/awesome-workshopper karlhorky/learn-to-program matteofigus/awesome-speaking lucasviola/awesome-tech-videos hangtwenty/dive-into-machine-learning watson/awesome-computer-history HollyAdele/awesome-programming-for-kids yrgo/awesome-educational-games micromata/awesome-javascript-learning micromata/awesome-css-learning dend/awesome-product-management liuchong/awesome-roadmaps JoseDeFreitas/awesome-youtubers paragonie/awesome-appsec sbilly/awesome-security apsdehal/awesome-ctf rshipp/awesome-malware-analysis ashishb/android-security-awesome carpedm20/awesome-hacking paralax/awesome-honeypots meirwah/awesome-incident-response jaredthecoder/awesome-vehicle-security qazbnm456/awesome-web-security fabacab/awesome-lockpicking fabacab/awesome-cybersecurity-blueteam cpuu/awesome-fuzzing fkie-cad/awesome-embedded-and-iot-security bakke92/awesome-gdpr TaptuIT/awesome-devsecops umbraco-community/awesome-umbraco refinerycms-contrib/awesome-refinerycms springload/awesome-wagtail drmonkeyninja/awesome-textpattern nirgn975/awesome-drupal craftcms/awesome MartinMiles/Awesome-Sitecore wernerkrauss/awesome-silverstripe-cms Kiloreux/awesome-robotics HQarroum/awesome-iot kitspace/awesome-electronics rabschi/awesome-beacon gitfrage/guitarspecs beardicus/awesome-plotters protontypes/awesome-robotic-tooling szenergy/awesome-lidar opencompany/awesome-open-company mmccaff/PlacesToPostYourStartup domenicosolazzo/awesome-okr LappleApple/awesome-leading-and-managing mezod/awesome-indie cjbarber/ToolsOfTheTrade nglgzz/awesome-clean-tech wardley-maps-community/awesome-wardley-maps RayBB/awesome-social-enterprise kdeldycke/awesome-engineering-team-management agamm/awesome-developer-first kdeldycke/awesome-billing matiassingers/awesome-slack filipelinhares/awesome-slack lukasz-madon/awesome-remote-job jyguyomarch/awesome-productivity tramcar/awesome-job-boards DopplerHQ/awesome-interview-questions joho/awesome-code-review j0hnm4r5/awesome-creative-technology lodthe/awesome-internships sdnds-tw/awesome-sdn briatte/awesome-network-analysis caesar0301/awesome-pcaptools rtckit/awesome-rtc igorbarinov/awesome-bitcoin vhpoet/awesome-ripple machinomy/awesome-non-financial-blockchain tleb/awesome-mastodon ttumiel/Awesome-Ethereum steven2358/awesome-blockchain-ai DanailMinchev/awesome-eosio chainstack/awesome-corda msmolyakov/awesome-waves substrate-developer-hub/awesome-substrate golemfactory/awesome-golem friedger/awesome-stacks-chain eselkin/awesome-computational-neuroscience maehr/awesome-digital-history writing-resources/awesome-scientific-writing danvoyce/awesome-creative-tech-events ildoc/awesome-italy-events awkward/awesome-netherlands-events TheJambo/awesome-testing mojoaxel/awesome-regression-testing christian-bromann/awesome-selenium SrinivasanTarget/awesome-appium sindresorhus/awesome-tap aliesbelik/awesome-jmeter k6io/awesome-k6 mxschmitt/awesome-playwright fityanos/awesome-quality-assurance-roadmap burningtree/awesome-json tmcw/awesome-geojson jdorfman/awesome-json-datasets secretGeek/awesomeCSV AchoArnold/discount-for-student-dev kyleterry/awesome-radio sindresorhus/awesome onurakpolat/awesome-analytics marmelab/awesome-rest cicdops/awesome-ciandcd mmcgrana/services-engineering ripienaar/free-for-dev cyberglot/awesome-answers diessica/awesome-sketch melvin0008/awesome-projects-boilerplates matiassingers/awesome-readme NARKOZ/guides kilimchoi/engineering-blogs awesome-selfhosted/awesome-selfhosted DataDaoDe/awesome-foss-apps alferov/awesome-gulp sindresorhus/amas stoeffel/awesome-ama-answers ibaaj/awesome-OpenSourcePhotography eug/awesome-opengl chentsulin/awesome-graphql APA-Technology-Division/urban-and-regional-planning-resources CUTR-at-USF/awesome-transit emptymalei/awesome-research fasouto/awesome-dataviz vinkla/shareable-links mfornos/awesome-microservices jagracey/Awesome-Unicode Codepoints/awesome-codepoints MunGell/awesome-for-beginners gamontal/awesome-katas drewrwilson/toolsforactivism dylanrees/citizen-science hobbyquaker/awesome-mqtt daviddias/awesome-hacking-locations cristianoliveira/awesome4girls vorpaljs/awesome-vorpal vinjn/awesome-vulkan egeerardyn/awesome-LaTeX antontarasenko/awesome-economics sublimino/awesome-funny-markov danielecook/Awesome-Bioinformatics hsiaoyi0504/awesome-cheminformatics Siddharth11/Colorful scholtzm/awesome-steam hackerkid/bots dastergon/awesome-sre KimberlyMunoz/empathy-in-engineering xen0l/awesome-dtrace bvolpato/awesome-userscripts tobiasbueschel/awesome-pokemon exAspArk/awesome-chatops kdeldycke/awesome-falsehood heynickc/awesome-ddd woop/awesome-quantified-self hbokh/awesome-saltstack nicolesaidy/awesome-web-design terkelg/awesome-creative-coding aviaryan/awesome-no-login-web-apps johnjago/awesome-free-software podo/awesome-framer BubuAnabelas/awesome-markdown mislavcimpersak/awesome-dev-fun kakoni/awesome-healthcare DavidLambauer/awesome-magento2 xiaohanyu/awesome-tikz analyticalmonk/awesome-neuroscience johnjago/awesome-ad-free angrykoala/awesome-esolangs roaldnefs/awesome-prometheus homematic-community/awesome-homematic sfischer13/awesome-ledger thomasbnt/awesome-web-monetization johnjago/awesome-uncopyright Zheaoli/awesome-coins folkswhocode/awesome-diversity zachflower/awesome-open-source-supporters robinstickel/awesome-design-principles johnjago/awesome-theravada inspectit-labs/awesome-inspectit nayafia/awesome-maintainers xxczaki/awesome-calculators ZYSzys/awesome-captcha markusschanta/awesome-jupyter andrewda/awesome-frc humanetech-community/awesome-humane-tech karlhorky/awesome-speakers edm00se/awesome-board-games uraimo/awesome-software-patreons ecohealthalliance/awesome-parasite jzarca01/awesome-food dreamingechoes/awesome-mental-health alexk111/awesome-bitcoin-payment-processors nschloe/awesome-scientific-computing ScaleLeap/awesome-amazon-seller brycejohnston/awesome-agriculture matttga/awesome-product-design catalinmiron/awesome-prisma simskij/awesome-software-architecture stevesong/awesome-connectivity-info stackshareio/awesome-stacks cytodata/awesome-cytodata davisonio/awesome-irc cenoura/awesome-ads philsturgeon/awesome-earth gruhn/awesome-naming caufieldjh/awesome-bioie iipc/awesome-web-archiving schlessera/awesome-wp-cli mourarthur/awesome-credit-modeling KeyboardInterrupt/awesome-ansible keller-mark/awesome-biological-visualizations aureooms/awesome-qr-code sdassow/awesome-veganism mbiesiad/awesome-translations dersvenhesse/awesome-scriptable topics/awesome https://awesome-indexed.mathew-davies.co.uk https://awesomelists.top basharovV/StumbleUponAwesome umutphp/awesome-cli http://awesome.digitalbunker.dev https://www.trackawesomelist.com sindresorhus/awesome-nodejs bcoe/awesome-cross-platform-nodejs dypsilon/frontend-dev-bookmarks vsouza/awesome-ios JStumpp/awesome-android weblancaster/awesome-IoT-hybrid sindresorhus/awesome-electron busterc/awesome-cordova jondot/awesome-react-native XamSome/awesome-xamarin inputsh/awesome-linux Friz-zy/awesome-linux-containers zoidbergwill/awesome-ebpf PandaFoss/Awesome-Arch iCHAIT/awesome-macOS herrbischoff/awesome-macos-command-line agarrharr/awesome-macos-screensavers jaywcjlove/awesome-mac serhii-londar/open-source-mac-os-apps yenchenlin/awesome-watchos deephacks/awesome-jvm mailtoharshit/awesome-salesforce donnemartin/awesome-aws Awesome-Windows/Awesome ipfs/awesome-ipfs fuse-compound/awesome-fuse ianstormtaylor/awesome-heroku thibmaek/awesome-raspberry-pi JesseTG/awesome-qt fregante/Awesome-WebExtensions motion-open-source/awesome-rubymotion vitalets/awesome-smart-tv Kazhnuz/awesome-gnome francoism90/awesome-kde quozd/awesome-dotnet thangchung/awesome-dotnet-core ironcev/awesome-roslyn miguelmota/awesome-amazon-alexa jonleibowitz/awesome-digitalocean Solido/awesome-flutter frenck/awesome-home-assistant victorshinya/awesome-ibmcloud jthegedus/awesome-firebase fkromer/awesome-ros2 adafruit/awesome-adafruitio irazasyed/awesome-cloudflare ravirupareliya/awesome-actions-on-google agucova/awesome-esp denolib/awesome-deno balintkissdev/awesome-dos nix-community/awesome-nix sorrycc/awesome-javascript wbinnssmith/awesome-promises standard/awesome-standard bolshchikov/js-must-watch loverajoel/jstips Kikobeats/awesome-network-js parro-it/awesome-micro-npm-packages feross/awesome-mad-science maxogden/maintenance-modules sindresorhus/awesome-npm avajs/awesome-ava dustinspecker/awesome-eslint stoeffel/awesome-fp-js sindresorhus/awesome-observables RyanZim/awesome-npm-scripts 30-seconds/30-seconds-of-code Richienb/awesome-ponyfills matteocrippa/awesome-swift hsavit1/Awesome-Swift-Education uraimo/Awesome-Swift-Playgrounds vinta/awesome-python timofurrer/awesome-asyncio faroit/awesome-python-scientific-audio adafruit/awesome-circuitpython krzjoa/awesome-python-data-science typeddjango/awesome-python-typing mcauser/awesome-micropython rust-unofficial/awesome-rust krispo/awesome-haskell passy/awesome-purescript avelino/awesome-go lauris/awesome-scala tindzk/awesome-scala-native markets/awesome-ruby razum2um/awesome-clojure hantuzun/awesome-clojurescript h4cc/awesome-elixir sporto/awesome-elm drobakowski/awesome-erlang svaksha/Julia.jl LewisJEllis/awesome-lua inputsh/awesome-c fffaraz/awesome-cpp qinwf/awesome-R iamericfletcher/awesome-r-learning-resources dlang-community/awesome-d CodyReichert/awesome-cl GustavBertram/awesome-common-lisp-learning hachiojipm/awesome-perl kdabir/awesome-groovy yissachar/awesome-dart akullpp/awesome-java eleventigers/awesome-rxjava KotlinBy/awesome-kotlin ocaml-community/awesome-ocaml seancoyne/awesome-coldfusion rabbiabram/awesome-fortran ziadoz/awesome-php jakoch/awesome-composer Fr0sT-Brutal/awesome-pascal ahkscript/awesome-AutoHotkey J2TeaM/awesome-AutoIt veelenga/awesome-crystal sfischer13/awesome-frege onqtam/awesome-cmake robinrodricks/awesome-actionscript3 sfischer13/awesome-eta joaomilho/awesome-idris ohenley/awesome-ada ebraminio/awesome-qsharp koolamusic/awesome-imba desiderantes/awesome-vala coq-community/awesome-coq vlang/awesome-v addyosmani/es6-tools davidsonfellipe/awesome-wpo lvwzhen/tools awesome-css-group/awesome-css addyosmani/critical-path-css-tools davidtheclark/scalable-css-reading-list AllThingsSmitty/must-watch-css AllThingsSmitty/css-protips troxler/awesome-css-frameworks enaqx/awesome-react expede/awesome-relay glauberfc/awesome-react-hooks mateusortiz/webcomponents-the-right-way Granze/awesome-polymer PatrickJS/awesome-angular sadcitizen/awesome-backbone diegocard/awesome-html5 willianjusten/awesome-svg raphamorim/awesome-canvas dnbard/awesome-knockout petk/awesome-dojo NoahBuscher/Inspire ember-community-russia/awesome-ember wasabeef/awesome-android-ui cjwirth/awesome-ios-ui Urigo/awesome-meteor sturobson/BEM-resources afonsopacifer/awesome-flexbox deanhume/typography brunopulis/awesome-a11y sachin1092/awesome-material wbkd/awesome-d3 jonathandion/awesome-emails petk/awesome-jquery AllThingsSmitty/jquery-tips-everyone-should-know notthetup/awesome-webaudio pazguille/offline-first agarrharr/awesome-static-website-services cyclejs-community/awesome-cyclejs dok/awesome-text-editing fliptheweb/motion-ui-design vuejs/awesome-vue sadcitizen/awesome-marionette aurelia-contrib/awesome-aurelia zingchart/awesome-charting candelibas/awesome-ionic ChromeDevTools/awesome-chrome-devtools jdrgomes/awesome-postcss nikgraf/awesome-draft-js TalAter/awesome-service-workers TalAter/awesome-progressive-web-apps choojs/awesome-choo brillout/awesome-redux webpack-contrib/awesome-webpack browserify/awesome-browserify Famolus/awesome-sass websemantics/awesome-ant-design LucasBassetti/awesome-less sjfricke/awesome-webgl preactjs/awesome-preact jbmoelker/progressive-enhancement-resources unicodeveloper/awesome-nextjs web-padawan/awesome-lit-html automata/awesome-jamstack henrikwirth/awesome-wordpress-gatsby myshov/awesome-mobile-web-development lauthieb/awesome-storybook AdrienTorris/awesome-blazor csabapalfi/awesome-pagespeed-metrics aniftyco/awesome-tailwindcss seed-rs/awesome-seed-rs pajaydev/awesome-web-performance-budget sergey-pimenov/awesome-web-animation jetli/awesome-yew nadunindunil/awesome-material-ui componently-com/awesome-building-blocks-for-web-apps TheComputerM/awesome-svelte klaufel/awesome-design-systems innocenzi/awesome-inertiajs mdbootstrap/awesome-mdbootstrap mjhea0/awesome-flask veggiemonk/awesome-docker iJackUA/awesome-vagrant uralbash/awesome-pyramid PerfectCarl/awesome-play1 friendsofcake/awesome-cakephp sitepoint-editors/awesome-symfony pehapkari/awesome-symfony-education chiraggude/awesome-laravel fukuball/Awesome-Laravel-Education blade-ui-kit/awesome-tall-stack gramantin/awesome-rails hothero/awesome-rails-gem phalcon/awesome-phalcon phanan/htaccess fcambus/nginx-resources stve/awesome-dropwizard ramitsurana/awesome-kubernetes unicodeveloper/awesome-lumen pmuens/awesome-serverless PhantomYdn/awesome-wicket vert-x3/vertx-awesome shuaibiyy/awesome-terraform Cellane/awesome-vapor ucg8j/awesome-dash mjhea0/awesome-fastapi kolomied/awesome-cdk kdeldycke/awesome-iam prakhar1989/awesome-courses academic/awesome-datascience siboehm/awesome-learn-datascience josephmisiti/awesome-machine-learning ujjwalkarn/Machine-Learning-Tutorials arbox/machine-learning-with-ruby likedan/Awesome-CoreML-Models h2oai/awesome-h2o SE-ML/awesome-seml georgezouq/awesome-ai-in-finance n2cholas/awesome-jax altamiracorp/awesome-xai edobashira/speech-language-processing dav009/awesome-spanish-nlp arbox/nlp-with-ruby seriousran/awesome-qa tokenmill/awesome-nlg theimpossibleastronaut/awesome-linguistics sobolevn/awesome-cryptography pFarb/awesome-crypto-papers jbhuang0604/awesome-computer-vision ChristosChristofidis/awesome-deep-learning jtoy/awesome-tensorflow aaronhma/awesome-tensorflow-js margaretmz/awesome-tensorflow-lite terryum/awesome-deep-learning-papers guillaume-chevalier/awesome-deep-learning-resources kjw0612/awesome-deep-vision ossu/computer-science lucasviola/awesome-functional-programming dspinellis/awesome-msr analysis-tools-dev/static-analysis harpribot/awesome-information-retrieval desireevl/awesome-quantum-computing mostafatouny/awesome-theoretical-computer-science onurakpolat/awesome-bigdata awesomedata/awesome-public-datasets youngwookim/awesome-hadoop igorbarinov/awesome-data-engineering manuzhang/awesome-streaming awesome-spark/awesome-spark ambster-public/awesome-qlik sduff/awesome-splunk papers-we-love/papers-we-love JanVanRyswyck/awesome-talks tayllan/awesome-algorithms gaerae/awesome-algorithms-education enjalot/algovis owainlewis/awesome-artificial-intelligence marcobiedermann/search-engine-optimization lnishan/awesome-competitive-programming rossant/awesome-math passy/awesome-recursion-schemes EbookFoundation/free-programming-books dariubs/GoBooks RomanTsegelskyi/rbooks hackerkid/Mind-Expanding-Books TalAter/awesome-book-authoring sger/ElixirBooks dreikanter/sublime-bookmarks mhinz/vim-galore emacs-tw/awesome-emacs mehcode/awesome-atom viatsko/awesome-vscode ellisonleao/magictools hzoo/awesome-gametalks godotengine/awesome-godot leereilly/games RyanNielson/awesome-unity hkirat/awesome-chess love2d-community/awesome-love2d pico-8/awesome-PICO-8 gbdev/awesome-gbdev WebCreationClub/awesome-construct stetso/awesome-gideros bs-community/awesome-minecraft leomaurodesenv/game-datasets Dvergar/awesome-haxe-gamedev rafaskb/awesome-libgdx playcanvas/awesome-playcanvas radek-sprta/awesome-game-remakes flame-engine/awesome-flame mhxion/awesome-discord-communities tobiasvl/awesome-chip-8 michelpereira/awesome-games-of-coding sindresorhus/quick-look-plugins jondot/awesome-devenv webpro/awesome-dotfiles alebcay/awesome-shell jorgebucaran/awsm.fish agarrharr/awesome-cli-apps unixorn/awesome-zsh-plugins phillipadsmith/awesome-github stefanbuck/awesome-browser-extensions-for-github tiimgreen/github-cheat-sheet matchai/awesome-pinned-gists arslanbilal/git-cheat-sheet git-tips/tips stevemao/awesome-git-addons compscilauren/awesome-git-hooks moul/awesome-ssh tvvocold/FOSS-for-Dev bnb/awesome-hyper janikvonrotz/awesome-powershell alfred-workflows/awesome-alfred-workflows k4m4/terminals-are-sexy sdras/awesome-actions sindresorhus/awesome-scifi RichardLitt/awesome-fantasy ayr-ton/awesome-geek-podcasts zudochkin/awesome-newsletters victorlaerte/awesome-it-quotes numetriclabz/awesome-db shlomi-noach/awesome-mysql dahlia/awesome-sqlalchemy mark-rushakoff/awesome-influxdb neueda/awesome-neo4j ramnes/awesome-mongodb d3viant0ne/awesome-rethinkdb mohataher/awesome-tinkerpop dhamaniasad/awesome-postgres quangv/awesome-couchdb rayokota/awesome-hbase erictleung/awesome-nosql-guides chrislatorres/awesome-contexture mgramin/awesome-db-tools vaticle/typedb-awesome Anant/awesome-cassandra shime/creative-commons-media brabadu/awesome-fonts chrissimpkins/codeface neutraltone/awesome-stock-resources davisonio/awesome-gif ciconia/awesome-music 44bits/awesome-opensource-documents willianjusten/awesome-audio-visualization ebu/awesome-broadcasting Siilwyn/awesome-pixel-art transitive-bullshit/awesome-ffmpeg notlmn/awesome-icons stingalleman/awesome-audiovisual mfkl/awesome-vlc therebelrobot/awesome-workshopper karlhorky/learn-to-program matteofigus/awesome-speaking lucasviola/awesome-tech-videos hangtwenty/dive-into-machine-learning watson/awesome-computer-history HollyAdele/awesome-programming-for-kids yrgo/awesome-educational-games micromata/awesome-javascript-learning micromata/awesome-css-learning dend/awesome-product-management liuchong/awesome-roadmaps JoseDeFreitas/awesome-youtubers paragonie/awesome-appsec sbilly/awesome-security apsdehal/awesome-ctf rshipp/awesome-malware-analysis ashishb/android-security-awesome carpedm20/awesome-hacking paralax/awesome-honeypots meirwah/awesome-incident-response jaredthecoder/awesome-vehicle-security qazbnm456/awesome-web-security fabacab/awesome-lockpicking fabacab/awesome-cybersecurity-blueteam cpuu/awesome-fuzzing fkie-cad/awesome-embedded-and-iot-security bakke92/awesome-gdpr TaptuIT/awesome-devsecops umbraco-community/awesome-umbraco refinerycms-contrib/awesome-refinerycms springload/awesome-wagtail drmonkeyninja/awesome-textpattern nirgn975/awesome-drupal craftcms/awesome MartinMiles/Awesome-Sitecore wernerkrauss/awesome-silverstripe-cms Kiloreux/awesome-robotics HQarroum/awesome-iot kitspace/awesome-electronics rabschi/awesome-beacon gitfrage/guitarspecs beardicus/awesome-plotters protontypes/awesome-robotic-tooling szenergy/awesome-lidar opencompany/awesome-open-company mmccaff/PlacesToPostYourStartup domenicosolazzo/awesome-okr LappleApple/awesome-leading-and-managing mezod/awesome-indie cjbarber/ToolsOfTheTrade nglgzz/awesome-clean-tech wardley-maps-community/awesome-wardley-maps RayBB/awesome-social-enterprise kdeldycke/awesome-engineering-team-management agamm/awesome-developer-first kdeldycke/awesome-billing matiassingers/awesome-slack filipelinhares/awesome-slack lukasz-madon/awesome-remote-job jyguyomarch/awesome-productivity tramcar/awesome-job-boards DopplerHQ/awesome-interview-questions joho/awesome-code-review j0hnm4r5/awesome-creative-technology lodthe/awesome-internships sdnds-tw/awesome-sdn briatte/awesome-network-analysis caesar0301/awesome-pcaptools rtckit/awesome-rtc igorbarinov/awesome-bitcoin vhpoet/awesome-ripple machinomy/awesome-non-financial-blockchain tleb/awesome-mastodon ttumiel/Awesome-Ethereum steven2358/awesome-blockchain-ai DanailMinchev/awesome-eosio chainstack/awesome-corda msmolyakov/awesome-waves substrate-developer-hub/awesome-substrate golemfactory/awesome-golem friedger/awesome-stacks-chain eselkin/awesome-computational-neuroscience maehr/awesome-digital-history writing-resources/awesome-scientific-writing danvoyce/awesome-creative-tech-events ildoc/awesome-italy-events awkward/awesome-netherlands-events TheJambo/awesome-testing mojoaxel/awesome-regression-testing christian-bromann/awesome-selenium SrinivasanTarget/awesome-appium sindresorhus/awesome-tap aliesbelik/awesome-jmeter k6io/awesome-k6 mxschmitt/awesome-playwright fityanos/awesome-quality-assurance-roadmap burningtree/awesome-json tmcw/awesome-geojson jdorfman/awesome-json-datasets secretGeek/awesomeCSV AchoArnold/discount-for-student-dev kyleterry/awesome-radio sindresorhus/awesome onurakpolat/awesome-analytics marmelab/awesome-rest cicdops/awesome-ciandcd mmcgrana/services-engineering ripienaar/free-for-dev cyberglot/awesome-answers diessica/awesome-sketch melvin0008/awesome-projects-boilerplates matiassingers/awesome-readme NARKOZ/guides kilimchoi/engineering-blogs awesome-selfhosted/awesome-selfhosted DataDaoDe/awesome-foss-apps alferov/awesome-gulp sindresorhus/amas stoeffel/awesome-ama-answers ibaaj/awesome-OpenSourcePhotography eug/awesome-opengl chentsulin/awesome-graphql APA-Technology-Division/urban-and-regional-planning-resources CUTR-at-USF/awesome-transit emptymalei/awesome-research fasouto/awesome-dataviz vinkla/shareable-links mfornos/awesome-microservices jagracey/Awesome-Unicode Codepoints/awesome-codepoints MunGell/awesome-for-beginners gamontal/awesome-katas drewrwilson/toolsforactivism dylanrees/citizen-science hobbyquaker/awesome-mqtt daviddias/awesome-hacking-locations cristianoliveira/awesome4girls vorpaljs/awesome-vorpal vinjn/awesome-vulkan egeerardyn/awesome-LaTeX antontarasenko/awesome-economics sublimino/awesome-funny-markov danielecook/Awesome-Bioinformatics hsiaoyi0504/awesome-cheminformatics Siddharth11/Colorful scholtzm/awesome-steam hackerkid/bots dastergon/awesome-sre KimberlyMunoz/empathy-in-engineering xen0l/awesome-dtrace bvolpato/awesome-userscripts tobiasbueschel/awesome-pokemon exAspArk/awesome-chatops kdeldycke/awesome-falsehood heynickc/awesome-ddd woop/awesome-quantified-self hbokh/awesome-saltstack nicolesaidy/awesome-web-design terkelg/awesome-creative-coding aviaryan/awesome-no-login-web-apps johnjago/awesome-free-software podo/awesome-framer BubuAnabelas/awesome-markdown mislavcimpersak/awesome-dev-fun kakoni/awesome-healthcare DavidLambauer/awesome-magento2 xiaohanyu/awesome-tikz analyticalmonk/awesome-neuroscience johnjago/awesome-ad-free angrykoala/awesome-esolangs roaldnefs/awesome-prometheus homematic-community/awesome-homematic sfischer13/awesome-ledger thomasbnt/awesome-web-monetization johnjago/awesome-uncopyright Zheaoli/awesome-coins folkswhocode/awesome-diversity zachflower/awesome-open-source-supporters robinstickel/awesome-design-principles johnjago/awesome-theravada inspectit-labs/awesome-inspectit nayafia/awesome-maintainers xxczaki/awesome-calculators ZYSzys/awesome-captcha markusschanta/awesome-jupyter andrewda/awesome-frc humanetech-community/awesome-humane-tech karlhorky/awesome-speakers edm00se/awesome-board-games uraimo/awesome-software-patreons ecohealthalliance/awesome-parasite jzarca01/awesome-food dreamingechoes/awesome-mental-health alexk111/awesome-bitcoin-payment-processors nschloe/awesome-scientific-computing ScaleLeap/awesome-amazon-seller brycejohnston/awesome-agriculture matttga/awesome-product-design catalinmiron/awesome-prisma simskij/awesome-software-architecture stevesong/awesome-connectivity-info stackshareio/awesome-stacks cytodata/awesome-cytodata davisonio/awesome-irc cenoura/awesome-ads philsturgeon/awesome-earth gruhn/awesome-naming caufieldjh/awesome-bioie iipc/awesome-web-archiving schlessera/awesome-wp-cli mourarthur/awesome-credit-modeling KeyboardInterrupt/awesome-ansible keller-mark/awesome-biological-visualizations aureooms/awesome-qr-code sdassow/awesome-veganism mbiesiad/awesome-translations dersvenhesse/awesome-scriptable topics/awesome https://awesome-indexed.mathew-davies.co.uk https://awesomelists.top basharovV/StumbleUponAwesome umutphp/awesome-cli http://awesome.digitalbunker.dev https://www.trackawesomelist.com
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Rendering Elements With React Rendering Elements Elements are the smallest building blocks of React apps. An element describes what you want to see on the screen: Unlike browser DOM elements, React elements are plain objects, and are cheap to create. React DOM takes care of updating the DOM to match the React elements. Note: One might confuse elements with a more widely known concept of “components”. We will introduce components in the next section. Elements are what components are “made of”, and we encourage you to read this section before jumping ahead. Rendering an Element into the DOM Let's say there is a <div> somewhere in your HTML file: We call this a “root” DOM node because everything inside it will be managed by React DOM. Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like. To render a React element into a root DOM node, pass both to ReactDOM.render(): Try it on CodePen It displays “Hello, world” on the page. Updating the Rendered Element React elements are immutable. Once you create an element, you can't change its children or attributes. An element is like a single frame in a movie: it represents the UI at a certain point in time. With our knowledge so far, the only way to update the UI is to create a new element, and pass it to ReactDOM.render(). Consider this ticking clock example: Try it on CodePen It calls ReactDOM.render() every second from a setInterval() callback. Note: In practice, most React apps only call ReactDOM.render() once. In the next sections we will learn how such code gets encapsulated into stateful components. We recommend that you don't skip topics because they build on each other. React Only Updates What's Necessary React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state. You can verify by inspecting the last example with the browser tools: Even though we create an element describing the whole UI tree on every tick, only the text node whose contents have changed gets updated by React DOM. In our experience, thinking about how the UI should look at any given moment, rather than how to change it over time, eliminates a whole class of bugs.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Intro To React Introduction to React for Complete Beginners All of the code examples below will be included a second time at the bottom of this article as an embedded gist. Introduction to React for Complete Beginners All of the code examples below will be included a second time at the bottom of this article as an embedded gist, so that it is properly syntax highlighted. React uses a syntax extension of JavaScript called JSX that allows you to write HTML directly within JavaScript. React React uses a syntax extension of JavaScript called JSX that allows you to write HTML directly within JavaScript because JSX is a syntactic extension of JavaScript, you can actually write JavaScript directly within JSX include the code you want to be treated as JavaScript within curly braces: { 'this is treated as JavaScript code' } JSX code must be compiled into JavaScript under the hood the challenges are calling ReactDOM.render (JSX, document.getElementById('root')) One important thing to know about nested JSX is that it must return a single element. For instance, several JSX elements written as siblings with no parent wrapper element will not transpile. From the React Docs: What is React? React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”. React has a few different kinds of components, but we'll start with React.Component subclasses: class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" /> We'll get to the funny XML-like tags soon. We use components to tell React what we want to see on the screen. When our data changes, React will efficiently update and re-render our components. Here, ShoppingList is a React component class, or React component type. A component takes in parameters, called props (short for “properties”), and returns a hierarchy of views to display via the render method. The render method returns a description of what you want to see on the screen. React takes the description and displays the result. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write. The <div /> syntax is transformed at build time to React.createElement('div'). The example above is equivalent to: return React.createElement('div', {className: 'shopping-list'}, React.createElement('h1', /* ... h1 children ... */), React.createElement('ul', /* ... ul children ... */) ); Valid JSX:<div> <p>Paragraph One</p> <p>Paragraph Two</p> <p>Paragraph Three</p> </div> Invalid JSX:<p>Paragraph One</p> <p>Paragraph Two</p> <p>Paragraph Three</p> To put comments inside JSX, you use the syntax {/* */} to wrap around the comment text. To put comments inside JSX, you use the syntax {/* */} to wrap around the comment text. The code editor has a JSX element similar to what you created in the last challenge. Add a comment somewhere within the provided div element, without modifying the existing h1 or p elements. const JSX = ( <div> {/* This is a comment */} <h1>This is a block of JSX</h1> <p>Here's a subtitle</p> </div> ); With React, we can render this JSX directly to the HTML DOM using React's rendering API known as ReactDOM. ReactDOM offers a simple method to render React elements to the DOM which looks like this: ReactDOM.render(componentToRender, targetNode) the first argument is the React element or component that you want to render, and the second argument is the DOM node that you want to render the component to. ReactDOM.render() must be called after the JSX element declarations, just like how you must declare variables before using them. key difference in JSX is that you can no longer use the word class to define HTML classes.— -> This is because class is a reserved word in JavaScript. Instead, JSX uses className the naming convention for all HTML attributes and event references in JSX become camelCase a click event in JSX is onClick, instead of onclick. Likewise, onchange becomes onChange. While this is a subtle difference, it is an important one to keep in mind moving forward. Apply a class of myDiv to the div provided in the JSX code. The constant JSX should return a div element. The div should have a class of myDiv. const JSX = ( <div> <h1>Add a class to this div</h1> </div> ); Ans: const JSX = ( <div className="myDiv"> <h1>Add a class to this div</h1> </div> ); React: Learn About Self-Closing JSX Tags-Another important way in which JSX differs from HTML is in the idea of the self-closing tag. In HTML, almost all tags have both an opening and closing tag: <div></div>; the closing tag always has a forward slash before the tag name that you are closing. there are special instances in HTML called “self-closing tags”, or tags that don't require both an opening and closing tag before another tag can start. For example the line-break tag can be written as <br> or as <br />, but should never be written as <br></br>, since it doesn't contain any content. In JSX, the rules are a little different. Any JSX element can be written with a self-closing tag, and every element must be closed. The line-break tag, for example, must always be written as <br /> in order to be valid JSX that can be transpiled. A <div>, on the other hand, can be written as <div /> or<div></div>. The difference is that in the first syntax version there is no way to include anything in the <div />. Fix the errors in the code editor so that it is valid JSX and successfully transpiles. Make sure you don't change any of the content — you only need to close tags where they are needed. const JSX = ( <div> <h2>Welcome to React!</h2> <br > <p>Be sure to close all tags!</p> <hr > </div> ); Ans: const JSX = ( <div> <h2>Welcome to React!</h2> <br /> <p>Be sure to close all tags!</p> <hr /> </div> ); React: Create a Stateless Functional Component There are two ways to create a React component. The first way is to use a JavaScript function. Defining a component in this way creates a stateless functional component. think of a stateless component as one that can receive data and render it, but does not manage or track changes to that data. To create a component with a function, you simply write a JavaScript function that returns either JSX or null React requires your function name to begin with a capital letter. Here's an example of a stateless functional component that assigns an HTML class in JSX:// After being transpiled, the <div> will have a CSS class of 'customClass' const DemoComponent = function() { return ( <div className='customClass' /> ); }; Because a JSX component represents HTML, you could put several components together to create a more complex HTML page. The code editor has a function called MyComponent. Complete this function so it returns a single div element which contains some string of text. Note: The text is considered a child of the div element, so you will not be able to use a self-closing tag. const MyComponent = function() { // Change code below this line // Change code above this line } ANS: const MyComponent = function() { // Change code below this line return ( <div> Some Text </div > ); // Change code above this line }; React: Create a React Component The other way to define a React component is with the ES6 class syntax. In the following example, Kitten extends React.Component: class Kitten extends React.Component { constructor(props) { super(props); } render() { return ( <h1>Hi</h1> ); } } This creates an ES6 class Kitten which extends the React.Component class. So the Kitten class now has access to many useful React features, such as local state and lifecycle hooks. Also notice the Kitten class has a constructor defined within it that calls super() It uses super() to call the constructor of the parent class, in this case React.Component The constructor is a special method used during the initialization of objects that are created with the class keyword. It is best practice to call a component's constructor with super, and pass props to both. This makes sure the component is initialized properly. For now, know that it is standard for this code to be included. MyComponent is defined in the code editor using class syntax. Finish writing the render method so it returns a div element that contains an h1 with the text Hello React!. class MyComponent extends React.Component { constructor(props) { super(props); } render() { // Change code below this line // Change code above this line } }; ANS: class MyComponent extends React.Component { constructor(props) { super(props); } render() { // Change code below this line return ( <div> <h1>Hello React!</h1> </div> ); // Change code above this line } }; React: Create a Component with Composition Imagine you are building an App and have created three components, a Navbar, Dashboard, and Footer. To compose these components together, you could create an App parent component which renders each of these three components as children. To render a component as a child in a React component, you include the component name written as a custom HTML tag in the JSX. For example, in the render method you could write: return ( <App> <Navbar /> <Dashboard /> <Footer /> </App> ) When React encounters a custom HTML tag that references another component (a component name wrapped in < /> like in this example), it renders the markup for that component in the location of the tag. This should illustrate the parent/child relationship between the App component and the Navbar, Dashboard, and Footer. Challenge: In the code editor, there is a simple functional component called ChildComponent and a class component called ParentComponent. Compose the two together by rendering the ChildComponent within the ParentComponent. Make sure to close the ChildComponent tag with a forward slash. Note: ChildComponent is defined with an ES6 arrow function because this is a very common practice when using React. However, know that this is just a function. const ChildComponent = () => { return ( <div> <p>I am the child</p> </div> ); }; class ParentComponent extends React.Component { constructor(props) { super(props); } render() { return ( <div> <h1>I am the parent</h1> { /* Change code below this line */ } { /* Change code above this line */ } </div> ); } }; ⌛The React component should return a single div element. ⌛The component should return two nested elements. ⌛The component should return the ChildComponent as its second child. Ans: const ChildComponent = () => { return ( <div> <p>I am the child</p> </div> ); }; class ParentComponent extends React.Component { constructor(props) { super(props); } render() { return ( <div> <h1>I am the parent</h1> { /* Change code below this line */ } { /* Change code above this line */ } </div> ); } }; More Examples: For more content follow me on GitHub: bgoonz - Overview Web Developer, Electrical Engineer https://bryanguner.medium.com/ https://portfolio42.netlify.app/… github.com More content at plainenglish.io By Bryan Guner on May 19, 2021. Canonical link Exported from Medium on May 23, 2021. Snippets: Renders an accordion menu with multiple collapsible content elements. Define an AccordionItem component, that renders a <button> which is used to update the component and notify its parent via the handleClick callback. Use the isCollapsed prop in AccordionItem to determine its appearance and set an appropriate className. Define an Accordion component that uses the useState() hook to initialize the value of the bindIndex state variable to defaultIndex. Filter children to remove unnecessary nodes except for AccordionItem by identifying the function's name. Use Array.prototype.map() on the collected nodes to render the individual collapsible elements. Define changeItem, which will be executed when clicking an AccordionItem's <button>. changeItem executes the passed callback, onItemClick, and updates bindIndex based on the clicked element..accordion-item.collapsed { display: none;}.accordion-item.expanded { display: block;}.accordion-button { display: block; width: 100%;} const AccordionItem = ({ label, isCollapsed, handleClick, children }) =&gt; { return ( &lt;&gt; &lt;button className=&quot;accordion-button&quot; onClick={handleClick}&gt; {label} &lt;/button&gt; &lt;div className={`accordion-item ${isCollapsed ? &quot;collapsed&quot; : &quot;expanded&quot;}`} aria-expanded={isCollapsed} &gt; {children} &lt;/div&gt; &lt;/&gt; ); }; const Accordion = ({ defaultIndex, onItemClick, children }) =&gt; { const [bindIndex, setBindIndex] = React.useState(defaultIndex); const changeItem = (itemIndex) =&gt; { if (typeof onItemClick === &quot;function&quot;) onItemClick(itemIndex); if (itemIndex !== bindIndex) setBindIndex(itemIndex); }; const items = children.filter((item) =&gt; item.type.name === &quot;AccordionItem&quot;); return ( &lt;&gt; {items.map(({ props }) =&gt; ( &lt;AccordionItem isCollapsed={bindIndex !== props.index} label={props.label} handleClick={() =&gt; changeItem(props.index)} children={props.children} /&gt; ))} &lt;/&gt; ); }; <hr /> ```js ReactDOM.render( &lt;Accordion defaultIndex=&quot;1&quot; onItemClick={console.log}&gt; &lt;AccordionItem label=&quot;A&quot; index=&quot;1&quot;&gt; Lorem ipsum &lt;/AccordionItem&gt; &lt;AccordionItem label=&quot;B&quot; index=&quot;2&quot;&gt; Dolor sit amet &lt;/AccordionItem&gt; &lt;/Accordion&gt;, document.getElementById(&quot;root&quot;) ); Renders an alert component with type prop. Use the useState() hook to create the isShown and isLeaving state variables and set both to false initially. Define timeoutId to keep the timer instance for clearing on component unmount. Use the useEffect() hook to update the value of isShown to true and clear the interval by using timeoutId when the component is unmounted. Define a closeAlert function to set the component as removed from the DOM by displaying a fading out animation and set isShown to false via setTimeout().@keyframes leave { 0% { opacity: 1; } 100% { opacity: 0; }}.alert { padding: 0.75 rem 0.5 rem; margin-bottom: 0.5 rem; text-align: left; padding-right: 40 px; border-radius: 4 px; font-size: 16 px; position: relative;}.alert.warning { color: #856404; background-color: #fff3cd; border-color: #ffeeba;}.alert.error { color: #721c24; background-color: #f8d7da; border-color: #f5c6cb;}.alert.leaving { animation: leave 0.5 s forwards;}.alert .close { position: absolute; top: 0; right: 0; padding: 0 0.75 rem; color: #333; border: 0; height: 100%; cursor: pointer; background: none; font-weight: 600; font-size: 16 px;}.alert .close:after { content: "x";} const Alert = ({ isDefaultShown = false, timeout = 250, type, message }) =&gt; { const [isShown, setIsShown] = React.useState(isDefaultShown); const [isLeaving, setIsLeaving] = React.useState(false); let timeoutId = null; React.useEffect(() =&gt; { setIsShown(true); return () =&gt; { clearTimeout(timeoutId); }; }, [isDefaultShown, timeout, timeoutId]); const closeAlert = () =&gt; { setIsLeaving(true); timeoutId = setTimeout(() =&gt; { setIsLeaving(false); setIsShown(false); }, timeout); }; return ( isShown &amp;&amp; ( &lt;div className={`alert ${type} ${isLeaving ? &quot;leaving&quot; : &quot;&quot;}`} role=&quot;alert&quot; &gt; &lt;button className=&quot;close&quot; onClick={closeAlert} /&gt; {message} &lt;/div&gt; ) ); }; <hr /> ```js ReactDOM.render( &lt;Alert type=&quot;info&quot; message=&quot;This is info&quot; /&gt;, document.getElementById(&quot;root&quot;) ); Renders a string as plaintext, with URLs converted to appropriate link elements. Use String.prototype.split() and String.prototype.match() with a regular expression to find URLs in a string. Return matched URLs rendered as <a> elements, dealing with missing protocol prefixes if necessary. Render the rest of the string as plaintext. const AutoLink = ({ text }) =&gt; { const delimiter = /((?:https?:\/\/)?(?:(?:[a-z0-9]?(?:[a-z0-9\-]{1,61}[a-z0-9])?\.[^\.|\s])+[a-z\.]*[a-z]+|(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})(?::\d{1,5})*[a-z0-9.,_\/~#&amp;=;%+?\-\\(\\)]*)/gi; return ( &lt;&gt; {text.split(delimiter).map((word) =&gt; { const match = word.match(delimiter); if (match) { const url = match[0]; return ( &lt;a href={url.startsWith(&quot;http&quot;) ? url : `http://${url}`}&gt;{url}&lt;/a&gt; ); } return word; })} &lt;/&gt; ); }; ReactDOM.render( &lt;AutoLink text=&quot;foo bar baz http://example.org bar&quot; /&gt;, document.getElementById(&quot;root&quot;) ); Renders a link formatted to call a phone number ( tel: link). Use phone to create a <a> element with an appropriate href attribute. Render the link with children as its content. const Callto = ({ phone, children }) =&gt; { return &lt;a href={`tel:${phone}`}&gt;{children}&lt;/a&gt;; }; ReactDOM.render( &lt;Callto phone=&quot;+302101234567&quot;&gt;Call me!&lt;/Callto&gt;, document.getElementById(&quot;root&quot;) ); Renders a carousel component. Use the useState() hook to create the active state variable and give it a value of 0 (index of the first item). Use the useEffect() hook to update the value of active to the index of the next item, using setTimeout. Compute the className for each carousel item while mapping over them and applying it accordingly. Render the carousel items using React.cloneElement() and pass down ...rest along with the computed className..carousel { position: relative;}.carousel-item { position: absolute; visibility: hidden;}.carousel-item.visible { visibility: visible;} const Carousel = ({ carouselItems, ...rest }) =&gt; { const [active, setActive] = React.useState(0); let scrollInterval = null; React.useEffect(() =&gt; { scrollInterval = setTimeout(() =&gt; { setActive((active + 1) % carouselItems.length); }, 2000); return () =&gt; clearTimeout(scrollInterval); }); return ( &lt;div className=&quot;carousel&quot;&gt; {carouselItems.map((item, index) =&gt; { const activeClass = active === index ? &quot; visible&quot; : &quot;&quot;; return React.cloneElement(item, { ...rest, className: `carousel-item${activeClass}`, }); })} &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render( &lt;Carousel carouselItems={[ &lt;div&gt;carousel item 1&lt;/div&gt;, &lt;div&gt;carousel item 2&lt;/div&gt;, &lt;div&gt;carousel item 3&lt;/div&gt;, ]} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a component with collapsible content. Use the useState() hook to create the isCollapsed state variable with an initial value of collapsed. Use the <button> to change the component's isCollapsed state and the content of the component, passed down via children. Determine the appearance of the content, based on isCollapsed and apply the appropriate className. Update the value of the aria-expanded attribute based on isCollapsed to make the component accessible..collapse-button { display: block; width: 100%;}.collapse-content.collapsed { display: none;}.collapsed-content.expanded { display: block;} const Collapse = ({ collapsed, children }) =&gt; { const [isCollapsed, setIsCollapsed] = React.useState(collapsed); return ( &lt;&gt; &lt;button className=&quot;collapse-button&quot; onClick={() =&gt; setIsCollapsed(!isCollapsed)} &gt; {isCollapsed ? &quot;Show&quot; : &quot;Hide&quot;} content &lt;/button&gt; &lt;div className={`collapse-content ${isCollapsed ? &quot;collapsed&quot; : &quot;expanded&quot;}`} aria-expanded={isCollapsed} &gt; {children} &lt;/div&gt; &lt;/&gt; ); }; <hr /> ```js ReactDOM.render( &lt;Collapse&gt; &lt;h1&gt;This is a collapse&lt;/h1&gt; &lt;p&gt;Hello world!&lt;/p&gt; &lt;/Collapse&gt;, document.getElementById(&quot;root&quot;) ); Renders a controlled <input> element that uses a callback function to inform its parent about value updates. Use the value passed down from the parent as the controlled input field's value. Use the onChange event to fire the onValueChange callback and send the new value to the parent. The parent must update the input field's value prop in order for its value to change on user input. const ControlledInput = ({ value, onValueChange, ...rest }) =&gt; { return ( &lt;input value={value} onChange={({ target: { value } }) =&gt; onValueChange(value)} {...rest} /&gt; ); }; const Form = () =&gt; { const [value, setValue] = React.useState(&quot;&quot;); return ( &lt;ControlledInput type=&quot;text&quot; placeholder=&quot;Insert some text here...&quot; value={value} onValueChange={setValue} /&gt; ); }; ReactDOM.render(&lt;Form /&gt;, document.getElementById(&quot;root&quot;)); Renders a countdown timer that prints a message when it reaches zero. Use the useState() hook to create a state variable to hold the time value, initialize it from the props and destructure it into its components. Use the useState() hook to create the paused and over state variables, used to prevent the timer from ticking if it's paused or the time has run out. Create a method tick, that updates the time values based on the current value (i.e. decreasing the time by one second). Create a method reset, that resets all state variables to their initial states. Use the the useEffect() hook to call the tick method every second via the use of setInterval() and use clearInterval() to clean up when the component is unmounted. Use String.prototype.padStart() to pad each part of the time array to two characters to create the visual representation of the timer. const CountDown = ({ hours = 0, minutes = 0, seconds = 0 }) =&gt; { const [paused, setPaused] = React.useState(false); const [over, setOver] = React.useState(false); const [[h, m, s], setTime] = React.useState([hours, minutes, seconds]); const tick = () =&gt; { if (paused || over) return; if (h === 0 &amp;&amp; m === 0 &amp;&amp; s === 0) setOver(true); else if (m === 0 &amp;&amp; s === 0) { setTime([h - 1, 59, 59]); } else if (s == 0) { setTime([h, m - 1, 59]); } else { setTime([h, m, s - 1]); } }; const reset = () =&gt; { setTime([parseInt(hours), parseInt(minutes), parseInt(seconds)]); setPaused(false); setOver(false); }; React.useEffect(() =&gt; { const timerID = setInterval(() =&gt; tick(), 1000); return () =&gt; clearInterval(timerID); }); return ( &lt;div&gt; &lt;p&gt;{`${h.toString().padStart(2, &quot;0&quot;)}:${m.toString().padStart(2, &quot;0&quot;)}:${s .toString() .padStart(2, &quot;0&quot;)}`}&lt;/p&gt; &lt;div&gt;{over ? &quot;Time's up!&quot; : &quot;&quot;}&lt;/div&gt; &lt;button onClick={() =&gt; setPaused(!paused)}&gt; {paused ? &quot;Resume&quot; : &quot;Pause&quot;} &lt;/button&gt; &lt;button onClick={() =&gt; reset()}&gt;Restart&lt;/button&gt; &lt;/div&gt; ); }; ReactDOM.render( &lt;CountDown hours={1} minutes={45} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a list of elements from an array of primitives. Use the value of the isOrdered prop to conditionally render an <ol> or a <ul> list. Use Array.prototype.map() to render every item in data as a <li> element with an appropriate key. const DataList = ({ isOrdered = false, data }) =&gt; { const list = data.map((val, i) =&gt; &lt;li key={`${i}_${val}`}&gt;{val}&lt;/li&gt;); return isOrdered ? &lt;ol&gt;{list}&lt;/ol&gt; : &lt;ul&gt;{list}&lt;/ul&gt;; }; const names = [&quot;John&quot;, &quot;Paul&quot;, &quot;Mary&quot;]; ReactDOM.render(&lt;DataList data={names} /&gt;, document.getElementById(&quot;root&quot;)); ReactDOM.render( &lt;DataList data={names} isOrdered /&gt;, document.getElementById(&quot;root&quot;) ); Renders a table with rows dynamically created from an array of primitives. Render a <table> element with two columns ( ID and Value). Use Array.prototype.map() to render every item in data as a <tr> element with an appropriate key. const DataTable = ({ data }) =&gt; { return ( &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;ID&lt;/th&gt; &lt;th&gt;Value&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; {data.map((val, i) =&gt; ( &lt;tr key={`${i}_${val}`}&gt; &lt;td&gt;{i}&lt;/td&gt; &lt;td&gt;{val}&lt;/td&gt; &lt;/tr&gt; ))} &lt;/tbody&gt; &lt;/table&gt; ); }; const people = [&quot;John&quot;, &quot;Jesse&quot;]; ReactDOM.render(&lt;DataTable data={people} /&gt;, document.getElementById(&quot;root&quot;)); Renders a file drag and drop component for a single file. Create a ref, called dropRef and bind it to the component's wrapper. Use the useState() hook to create the drag and filename variables, initialized to false and '' respectively. The variables dragCounter and drag are used to determine if a file is being dragged, while filename is used to store the dropped file's name. Create the handleDrag, handleDragIn, handleDragOut and handleDrop methods to handle drag and drop functionality. handleDrag prevents the browser from opening the dragged file, handleDragIn and handleDragOut handle the dragged file entering and exiting the component, while handleDrop handles the file being dropped and passes it to onDrop. Use the useEffect() hook to handle each of the drag and drop events using the previously created methods..filedrop { min-height: 120 px; border: 3 px solid #d3d3d3; text-align: center; font-size: 24 px; padding: 32 px; border-radius: 4 px;}.filedrop.drag { border: 3 px dashed #1e90ff;}.filedrop.ready { border: 3 px solid #32cd32;} const FileDrop = ({ onDrop }) =&gt; { const [drag, setDrag] = React.useState(false); const [filename, setFilename] = React.useState(&quot;&quot;); let dropRef = React.createRef(); let dragCounter = 0; const handleDrag = (e) =&gt; { e.preventDefault(); e.stopPropagation(); }; const handleDragIn = (e) =&gt; { e.preventDefault(); e.stopPropagation(); dragCounter++; if (e.dataTransfer.items &amp;&amp; e.dataTransfer.items.length &gt; 0) setDrag(true); }; const handleDragOut = (e) =&gt; { e.preventDefault(); e.stopPropagation(); dragCounter--; if (dragCounter === 0) setDrag(false); }; const handleDrop = (e) =&gt; { e.preventDefault(); e.stopPropagation(); setDrag(false); if (e.dataTransfer.files &amp;&amp; e.dataTransfer.files.length &gt; 0) { onDrop(e.dataTransfer.files[0]); setFilename(e.dataTransfer.files[0].name); e.dataTransfer.clearData(); dragCounter = 0; } }; React.useEffect(() =&gt; { let div = dropRef.current; div.addEventListener(&quot;dragenter&quot;, handleDragIn); div.addEventListener(&quot;dragleave&quot;, handleDragOut); div.addEventListener(&quot;dragover&quot;, handleDrag); div.addEventListener(&quot;drop&quot;, handleDrop); return () =&gt; { div.removeEventListener(&quot;dragenter&quot;, handleDragIn); div.removeEventListener(&quot;dragleave&quot;, handleDragOut); div.removeEventListener(&quot;dragover&quot;, handleDrag); div.removeEventListener(&quot;drop&quot;, handleDrop); }; }); return ( &lt;div ref={dropRef} className={ drag ? &quot;filedrop drag&quot; : filename ? &quot;filedrop ready&quot; : &quot;filedrop&quot; } &gt; {filename &amp;&amp; !drag ? &lt;div&gt;{filename}&lt;/div&gt; : &lt;div&gt;Drop a file here!&lt;/div&gt;} &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render( &lt;FileDrop onDrop={console.log} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a textarea component with a character limit. Use the useState() hook to create the content state variable and set its value to that of value prop, trimmed down to limit characters. Create a method setFormattedContent, which trims the content down to limit characters and memoize it, using the useCallback() hook. Bind the onChange event of the <textarea> to call setFormattedContent with the value of the fired event. const LimitedTextarea = ({ rows, cols, value, limit }) =&gt; { const [content, setContent] = React.useState(value.slice(0, limit)); const setFormattedContent = React.useCallback( (text) =&gt; { setContent(text.slice(0, limit)); }, [limit, setContent] ); return ( &lt;&gt; &lt;textarea rows={rows} cols={cols} onChange={(event) =&gt; setFormattedContent(event.target.value)} value={content} /&gt; &lt;p&gt; {content.length}/{limit} &lt;/p&gt; &lt;/&gt; ); }; ReactDOM.render( &lt;LimitedTextarea limit={32} value=&quot;Hello!&quot; /&gt;, document.getElementById(&quot;root&quot;) ); Renders a textarea component with a word limit. Use the useState() hook to create a state variable, containing content and wordCount, using the value prop and 0 as the initial values respectively. Use the useCallback() hooks to create a memoized function, setFormattedContent, that uses String.prototype.split() to turn the input into an array of words. Check if the result of applying Array.prototype.filter() combined with Boolean has a length longer than limit and, if so, trim the input, otherwise return the raw input, updating state accordingly in both cases. Use the useEffect() hook to call the setFormattedContent method on the value of the content state variable during the initial render. Bind the onChange event of the <textarea> to call setFormattedContent with the value of event.target.value. const LimitedWordTextarea = ({ rows, cols, value, limit }) =&gt; { const [{ content, wordCount }, setContent] = React.useState({ content: value, wordCount: 0, }); const setFormattedContent = React.useCallback( (text) =&gt; { let words = text.split(&quot; &quot;).filter(Boolean); if (words.length &gt; limit) { setContent({ content: words.slice(0, limit).join(&quot; &quot;), wordCount: limit, }); } else { setContent({ content: text, wordCount: words.length }); } }, [limit, setContent] ); React.useEffect(() =&gt; { setFormattedContent(content); }, []); return ( &lt;&gt; &lt;textarea rows={rows} cols={cols} onChange={(event) =&gt; setFormattedContent(event.target.value)} value={content} /&gt; &lt;p&gt; {wordCount}/{limit} &lt;/p&gt; &lt;/&gt; ); }; ReactDOM.render( &lt;LimitedWordTextarea limit={5} value=&quot;Hello there!&quot; /&gt;, document.getElementById(&quot;root&quot;) ); Renders a spinning loader component. Render an SVG, whose height and width are determined by the size prop. Use CSS to animate the SVG, creating a spinning animation..loader { animation: rotate 2 s linear infinite;}@keyframes rotate { 100% { transform: rotate( 360 deg); }}.loader circle { animation: dash 1.5 s ease-in-out infinite;}@keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; }} const Loader = ({ size }) =&gt; { return ( &lt;svg className=&quot;loader&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width={size} height={size} viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; strokeWidth=&quot;2&quot; strokeLinecap=&quot;round&quot; strokeLinejoin=&quot;round&quot; &gt; &lt;circle cx=&quot;12&quot; cy=&quot;12&quot; r=&quot;10&quot; /&gt; &lt;/svg&gt; ); }; <hr /> ```js ReactDOM.render(&lt;Loader size={24} /&gt;, document.getElementById(&quot;root&quot;)); Renders a link formatted to send an email ( mailto: link). Use the email, subject and body props to create a <a> element with an appropriate href attribute. Use encodeURIcomponent to safely encode the subject and body into the link URL. Render the link with children as its content. const Mailto = ({ email, subject = &quot;&quot;, body = &quot;&quot;, children }) =&gt; { let params = subject || body ? &quot;?&quot; : &quot;&quot;; if (subject) params += `subject=${encodeURIComponent(subject)}`; if (body) params += `${subject ? &quot;&amp;&quot; : &quot;&quot;}body=${encodeURIComponent(body)}`; return &lt;a href={`mailto:${email}${params}`}&gt;{children}&lt;/a&gt;; }; ReactDOM.render( &lt;Mailto email=&quot;foo@bar.baz&quot; subject=&quot;Hello &amp; Welcome&quot; body=&quot;Hello world!&quot;&gt; Mail me! &lt;/Mailto&gt;, document.getElementById(&quot;root&quot;) ); Renders a table with rows dynamically created from an array of objects and a list of property names. Use Object.keys(), Array.prototype.filter(), Array.prototype.includes() and Array.prototype.reduce() to produce a filteredData array, containing all objects with the keys specified in propertyNames. Render a <table> element with a set of columns equal to the amount of values in propertyNames. Use Array.prototype.map() to render each value in the propertyNames array as a <th> element. Use Array.prototype.map() to render each object in the filteredData array as a <tr> element, containing a <td> for each key in the object. This component does not work with nested objects and will break if there are nested objects inside any of the properties specified in propertyNames const MappedTable = ({ data, propertyNames }) =&gt; { let filteredData = data.map((v) =&gt; Object.keys(v) .filter((k) =&gt; propertyNames.includes(k)) .reduce((acc, key) =&gt; ((acc[key] = v[key]), acc), {}) ); return ( &lt;table&gt; &lt;thead&gt; &lt;tr&gt; {propertyNames.map((val) =&gt; ( &lt;th key={`h_${val}`}&gt;{val}&lt;/th&gt; ))} &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; {filteredData.map((val, i) =&gt; ( &lt;tr key={`i_${i}`}&gt; {propertyNames.map((p) =&gt; ( &lt;td key={`i_${i}_${p}`}&gt;{val[p]}&lt;/td&gt; ))} &lt;/tr&gt; ))} &lt;/tbody&gt; &lt;/table&gt; ); }; const people = [ { name: &quot;John&quot;, surname: &quot;Smith&quot;, age: 42 }, { name: &quot;Adam&quot;, surname: &quot;Smith&quot;, gender: &quot;male&quot; }, ]; const propertyNames = [&quot;name&quot;, &quot;surname&quot;, &quot;age&quot;]; ReactDOM.render( &lt;MappedTable data={people} propertyNames={propertyNames} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a Modal component, controllable through events. Define keydownHandler, a method which handles all keyboard events and is used to call onClose when the Esc key is pressed. Use the useEffect() hook to add or remove the keydown event listener to the document, calling keydownHandler for every event. Add a styled <span> element that acts as a close button, calling onClose when clicked. Use the isVisible prop passed down from the parent to determine if the modal should be displayed or not. To use the component, import Modal only once and then display it by passing a boolean value to the isVisible attribute..modal { position: fixed; top: 0; bottom: 0; left: 0; right: 0; width: 100%; z-index: 9999; display: flex; align-items: center; justify-content: center; background-color: rgba( 0, 0, 0, 0.25); animation-name: appear; animation-duration: 300 ms;}.modal-dialog { width: 100%; max-width: 550 px; background: white; position: relative; margin: 0 20 px; max-height: calc( 100 vh - 40 px); text-align: left; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 4 px 8 px 0 rgba( 0, 0, 0, 0.2), 0 6 px 20 px 0 rgba( 0, 0, 0, 0.19); -webkit-animation-name: animatetop; -webkit-animation-duration: 0.4 s; animation-name: slide-in; animation-duration: 0.5 s;}.modal-header,.modal-footer { display: flex; align-items: center; padding: 1 rem;}.modal-header { border-bottom: 1 px solid #dbdbdb; justify-content: space-between;}.modal-footer { border-top: 1 px solid #dbdbdb; justify-content: flex-end;}.modal-close { cursor: pointer; padding: 1 rem; margin: -1 rem -1 rem -1 rem auto;}.modal-body { overflow: auto;}.modal-content { padding: 1 rem;}@keyframes appear { from { opacity: 0; } to { opacity: 1; }}@keyframes slide-in { from { transform: translateY(-150 px); } to { transform: translateY( 0); }} const Modal = ({ isVisible = false, title, content, footer, onClose }) =&gt; { const keydownHandler = ({ key }) =&gt; { switch (key) { case &quot;Escape&quot;: onClose(); break; default: } }; React.useEffect(() =&gt; { document.addEventListener(&quot;keydown&quot;, keydownHandler); return () =&gt; document.removeEventListener(&quot;keydown&quot;, keydownHandler); }); return !isVisible ? null : ( &lt;div className=&quot;modal&quot; onClick={onClose}&gt; &lt;div className=&quot;modal-dialog&quot; onClick={(e) =&gt; e.stopPropagation()}&gt; &lt;div className=&quot;modal-header&quot;&gt; &lt;h3 className=&quot;modal-title&quot;&gt;{title}&lt;/h3&gt; &lt;span className=&quot;modal-close&quot; onClick={onClose}&gt; &amp;times; &lt;/span&gt; &lt;/div&gt; &lt;div className=&quot;modal-body&quot;&gt; &lt;div className=&quot;modal-content&quot;&gt;{content}&lt;/div&gt; &lt;/div&gt; {footer &amp;&amp; &lt;div className=&quot;modal-footer&quot;&gt;{footer}&lt;/div&gt;} &lt;/div&gt; &lt;/div&gt; ); }; <hr /> ```js const App = () =&gt; { const [isModal, setModal] = React.useState(false); return ( &lt;&gt; &lt;button onClick={() =&gt; setModal(true)}&gt;Click Here&lt;/button&gt; &lt;Modal isVisible={isModal} title=&quot;Modal Title&quot; content={&lt;p&gt;Add your content here&lt;/p&gt;} footer={&lt;button&gt;Cancel&lt;/button&gt;} onClose={() =&gt; setModal(false)} /&gt; &lt;/&gt; ); }; ReactDOM.render(&lt;App /&gt;, document.getElementById(&quot;root&quot;)); Renders a checkbox list that uses a callback function to pass its selected value/values to the parent component. Use the useState() hook to create the data state variable and use the options prop to initialize its value. Create a toggle function that uses the spread operator (...) and Array.prototype.splice() to update the data state variable and call the onChange callback with any checked options. Use Array.prototype.map() to map the data state variable to individual <input type="checkbox"> elements, each one wrapped in a <label>, binding the onClick handler to the toggle function. const MultiselectCheckbox = ({ options, onChange }) =&gt; { const [data, setData] = React.useState(options); const toggle = (index) =&gt; { const newData = [...data]; newData.splice(index, 1, { label: data[index].label, checked: !data[index].checked, }); setData(newData); onChange(newData.filter((x) =&gt; x.checked)); }; return ( &lt;&gt; {data.map((item, index) =&gt; ( &lt;label key={item.label}&gt; &lt;input readOnly type=&quot;checkbox&quot; checked={item.checked || false} onClick={() =&gt; toggle(index)} /&gt; {item.label} &lt;/label&gt; ))} &lt;/&gt; ); }; const options = [{ label: &quot;Item One&quot; }, { label: &quot;Item Two&quot; }]; ReactDOM.render( &lt;MultiselectCheckbox options={options} onChange={(data) =&gt; { console.log(data); }} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a password input field with a reveal button. Use the useState() hook to create the shown state variable and set its value to false. When the <button> is clicked, execute setShown, toggling the type of the <input> between "text" and "password". const PasswordRevealer = ({ value }) =&gt; { const [shown, setShown] = React.useState(false); return ( &lt;&gt; &lt;input type={shown ? &quot;text&quot; : &quot;password&quot;} value={value} /&gt; &lt;button onClick={() =&gt; setShown(!shown)}&gt;Show/Hide&lt;/button&gt; &lt;/&gt; ); }; ReactDOM.render(&lt;PasswordRevealer /&gt;, document.getElementById(&quot;root&quot;)); Renders a button that animates a ripple effect when clicked. Use the useState() hook to create the coords and isRippling state variables for the pointer's coordinates and the animation state of the button respectively. Use a useEffect() hook to change the value of isRippling every time the coords state variable changes, starting the animation. Use setTimeout() in the previous hook to clear the animation after it's done playing. Use a useEffect() hook to reset coords whenever the isRippling state variable is false. Handle the onClick event by updating the coords state variable and calling the passed callback..ripple-button { border-radius: 4 px; border: none; margin: 8 px; padding: 14 px 24 px; background: #1976d2; color: #fff; overflow: hidden; position: relative; cursor: pointer;}.ripple-button > .ripple { width: 20 px; height: 20 px; position: absolute; background: #63a4ff; display: block; content: ""; border-radius: 9999 px; opacity: 1; animation: 0.9 s ease 1 forwards ripple-effect;}@keyframes ripple-effect { 0% { transform: scale( 1); opacity: 1; } 50% { transform: scale( 10); opacity: 0.375; } 100% { transform: scale( 35); opacity: 0; }}.ripple-button > .content { position: relative; z-index: 2;} const RippleButton = ({ children, onClick }) =&gt; { const [coords, setCoords] = React.useState({ x: -1, y: -1 }); const [isRippling, setIsRippling] = React.useState(false); React.useEffect(() =&gt; { if (coords.x !== -1 &amp;&amp; coords.y !== -1) { setIsRippling(true); setTimeout(() =&gt; setIsRippling(false), 300); } else setIsRippling(false); }, [coords]); React.useEffect(() =&gt; { if (!isRippling) setCoords({ x: -1, y: -1 }); }, [isRippling]); return ( &lt;button className=&quot;ripple-button&quot; onClick={(e) =&gt; { const rect = e.target.getBoundingClientRect(); setCoords({ x: e.clientX - rect.left, y: e.clientY - rect.top }); onClick &amp;&amp; onClick(e); }} &gt; {isRippling ? ( &lt;span className=&quot;ripple&quot; style={{ left: coords.x, top: coords.y, }} /&gt; ) : ( &quot;&quot; )} &lt;span className=&quot;content&quot;&gt;{children}&lt;/span&gt; &lt;/button&gt; ); }; <hr /> ```js ReactDOM.render( &lt;RippleButton onClick={(e) =&gt; console.log(e)}&gt;Click me&lt;/RippleButton&gt;, document.getElementById(&quot;root&quot;) ); Renders an uncontrolled <select> element that uses a callback function to pass its value to the parent component. Use the the selectedValue prop as the defaultValue of the <select> element to set its initial value.. Use the onChange event to fire the onValueChange callback and send the new value to the parent. Use Array.prototype.map() on the values array to create an <option> element for each passed value. Each item in values must be a 2-element array, where the first element is the value of the item and the second one is the displayed text for it. const Select = ({ values, onValueChange, selectedValue, ...rest }) =&gt; { return ( &lt;select defaultValue={selectedValue} onChange={({ target: { value } }) =&gt; onValueChange(value)} {...rest} &gt; {values.map(([value, text]) =&gt; ( &lt;option key={value} value={value}&gt; {text} &lt;/option&gt; ))} &lt;/select&gt; ); }; const choices = [ [&quot;grapefruit&quot;, &quot;Grapefruit&quot;], [&quot;lime&quot;, &quot;Lime&quot;], [&quot;coconut&quot;, &quot;Coconut&quot;], [&quot;mango&quot;, &quot;Mango&quot;], ]; ReactDOM.render( &lt;Select values={choices} selectedValue=&quot;lime&quot; onValueChange={(val) =&gt; console.log(val)} /&gt;, document.getElementById(&quot;root&quot;) ); Renders an uncontrolled range input element that uses a callback function to pass its value to the parent component. Set the type of the <input> element to "range" to create a slider. Use the defaultValue passed down from the parent as the uncontrolled input field's initial value. Use the onChange event to fire the onValueChange callback and send the new value to the parent. const Slider = ({ min = 0, max = 100, defaultValue, onValueChange, ...rest }) =&gt; { return ( &lt;input type=&quot;range&quot; min={min} max={max} defaultValue={defaultValue} onChange={({ target: { value } }) =&gt; onValueChange(value)} {...rest} /&gt; ); }; ReactDOM.render( &lt;Slider onValueChange={(val) =&gt; console.log(val)} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a star rating component. Define a component, called Star that will render each individual star with the appropriate appearance, based on the parent component's state. In the StarRating component, use the useState() hook to define the rating and selection state variables with the appropriate initial values. Create a method, hoverOver, that updates selected according to the provided event, using the . data-star-id attribute of the event's target or resets it to 0 if called with a null argument. Use Array.from() to create an array of 5 elements and Array.prototype.map() to create individual <Star> components. Handle the onMouseOver and onMouseLeave events of the wrapping element using hoverOver and the onClick event using setRating..star { color: #ff9933; cursor: pointer;} const Star = ({ marked, starId }) =&gt; { return ( &lt;span data-star-id={starId} className=&quot;star&quot; role=&quot;button&quot;&gt; {marked ? &quot;\u2605&quot; : &quot;\u2606&quot;} &lt;/span&gt; ); }; const StarRating = ({ value }) =&gt; { const [rating, setRating] = React.useState(parseInt(value) || 0); const [selection, setSelection] = React.useState(0); const hoverOver = (event) =&gt; { let val = 0; if (event &amp;&amp; event.target &amp;&amp; event.target.getAttribute(&quot;data-star-id&quot;)) val = event.target.getAttribute(&quot;data-star-id&quot;); setSelection(val); }; return ( &lt;div onMouseOut={() =&gt; hoverOver(null)} onClick={(e) =&gt; setRating(e.target.getAttribute(&quot;data-star-id&quot;) || rating) } onMouseOver={hoverOver} &gt; {Array.from({ length: 5 }, (v, i) =&gt; ( &lt;Star starId={i + 1} key={`star_${i + 1}`} marked={selection ? selection &gt;= i + 1 : rating &gt;= i + 1} /&gt; ))} &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render(&lt;StarRating value={2} /&gt;, document.getElementById(&quot;root&quot;)); Renders a tabbed menu and view component. Define a Tabs component that uses the useState() hook to initialize the value of the bindIndex state variable to defaultIndex. Define a TabItem component and filter children passed to the Tabs component to remove unnecessary nodes except for TabItem by identifying the function's name. Define changeTab, which will be executed when clicking a <button> from the menu. changeTab executes the passed callback, onTabClick, and updates bindIndex based on the clicked element. Use Array.prototype.map() on the collected nodes to render the menu and view of the tabs, using the value of binIndex to determine the active tab and apply the correct className..tab-menu > button { cursor: pointer; padding: 8 px 16 px; border: 0; border-bottom: 2 px solid transparent; background: none;}.tab-menu > button.focus { border-bottom: 2 px solid #007bef;}.tab-menu > button:hover { border-bottom: 2 px solid #007bef;}.tab-content { display: none;}.tab-content.selected { display: block;} const TabItem = (props) =&gt; &lt;div {...props} /&gt;; const Tabs = ({ defaultIndex = 0, onTabClick, children }) =&gt; { const [bindIndex, setBindIndex] = React.useState(defaultIndex); const changeTab = (newIndex) =&gt; { if (typeof onItemClick === &quot;function&quot;) onItemClick(itemIndex); setBindIndex(newIndex); }; const items = children.filter((item) =&gt; item.type.name === &quot;TabItem&quot;); return ( &lt;div className=&quot;wrapper&quot;&gt; &lt;div className=&quot;tab-menu&quot;&gt; {items.map(({ props: { index, label } }) =&gt; ( &lt;button key={`tab-btn-${index}`} onClick={() =&gt; changeTab(index)} className={bindIndex === index ? &quot;focus&quot; : &quot;&quot;} &gt; {label} &lt;/button&gt; ))} &lt;/div&gt; &lt;div className=&quot;tab-view&quot;&gt; {items.map(({ props }) =&gt; ( &lt;div {...props} className={`tab-content ${ bindIndex === props.index ? &quot;selected&quot; : &quot;&quot; }`} key={`tab-content-${props.index}`} /&gt; ))} &lt;/div&gt; &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render( &lt;Tabs defaultIndex=&quot;1&quot; onTabClick={console.log}&gt; &lt;TabItem label=&quot;A&quot; index=&quot;1&quot;&gt; Lorem ipsum &lt;/TabItem&gt; &lt;TabItem label=&quot;B&quot; index=&quot;2&quot;&gt; Dolor sit amet &lt;/TabItem&gt; &lt;/Tabs&gt;, document.getElementById(&quot;root&quot;) ); Renders a tag input field. Define a TagInput component and use the useState() hook to initialize an array from tags. Use Array.prototype.map() on the collected nodes to render the list of tags. Define the addTagData method, which will be executed when pressing the Enter key. The addTagData method calls setTagData to add the new tag using the spread (...) operator to prepend the existing tags and add the new tag at the end of the tagData array. Define the removeTagData method, which will be executed on clicking the delete icon in the tag. Use Array.prototype.filter() in the removeTagData method to remove the tag using its index to filter it out from the tagData array..tag-input { display: flex; flex-wrap: wrap; min-height: 48 px; padding: 0 8 px; border: 1 px solid #d6d8da; border-radius: 6 px;}.tag-input input { flex: 1; border: none; height: 46 px; font-size: 14 px; padding: 4 px 0 0;}.tag-input input:focus { outline: transparent;}.tags { display: flex; flex-wrap: wrap; padding: 0; margin: 8 px 0 0;}.tag { width: auto; height: 32 px; display: flex; align-items: center; justify-content: center; color: #fff; padding: 0 8 px; font-size: 14 px; list-style: none; border-radius: 6 px; margin: 0 8 px 8 px 0; background: #0052cc;}.tag-title { margin-top: 3 px;}.tag-close-icon { display: block; width: 16 px; height: 16 px; line-height: 16 px; text-align: center; font-size: 14 px; margin-left: 8 px; color: #0052cc; border-radius: 50%; background: #fff; cursor: pointer;} const TagInput = ({ tags }) =&gt; { const [tagData, setTagData] = React.useState(tags); const removeTagData = (indexToRemove) =&gt; { setTagData([...tagData.filter((_, index) =&gt; index !== indexToRemove)]); }; const addTagData = (event) =&gt; { if (event.target.value !== &quot;&quot;) { setTagData([...tagData, event.target.value]); event.target.value = &quot;&quot;; } }; return ( &lt;div className=&quot;tag-input&quot;&gt; &lt;ul className=&quot;tags&quot;&gt; {tagData.map((tag, index) =&gt; ( &lt;li key={index} className=&quot;tag&quot;&gt; &lt;span className=&quot;tag-title&quot;&gt;{tag}&lt;/span&gt; &lt;span className=&quot;tag-close-icon&quot; onClick={() =&gt; removeTagData(index)} &gt; x &lt;/span&gt; &lt;/li&gt; ))} &lt;/ul&gt; &lt;input type=&quot;text&quot; onKeyUp={(event) =&gt; (event.key === &quot;Enter&quot; ? addTagData(event) : null)} placeholder=&quot;Press enter to add a tag&quot; /&gt; &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render( &lt;TagInput tags={[&quot;Nodejs&quot;, &quot;MongoDB&quot;]} /&gt;, document.getElementById(&quot;root&quot;) ); Renders an uncontrolled <textarea> element that uses a callback function to pass its value to the parent component. Use the defaultValue passed down from the parent as the uncontrolled input field's initial value. Use the onChange event to fire the onValueChange callback and send the new value to the parent. const TextArea = ({ cols = 20, rows = 2, defaultValue, onValueChange, ...rest }) =&gt; { return ( &lt;textarea cols={cols} rows={rows} defaultValue={defaultValue} onChange={({ target: { value } }) =&gt; onValueChange(value)} {...rest} /&gt; ); }; ReactDOM.render( &lt;TextArea placeholder=&quot;Insert some text here...&quot; onValueChange={(val) =&gt; console.log(val)} /&gt;, document.getElementById(&quot;root&quot;) ); Renders a toggle component. Use the useState() hook to initialize the isToggleOn state variable to defaultToggled. Render an <input> and bind its onClick event to update the isToggledOn state variable, applying the appropriate className to the wrapping <label>..toggle input[type="checkbox"] { display: none;}.toggle.on { background-color: green;}.toggle.off { background-color: red;} const Toggle = ({ defaultToggled = false }) =&gt; { const [isToggleOn, setIsToggleOn] = React.useState(defaultToggled); return ( &lt;label className={isToggleOn ? &quot;toggle on&quot; : &quot;toggle off&quot;}&gt; &lt;input type=&quot;checkbox&quot; checked={isToggleOn} onChange={() =&gt; setIsToggleOn(!isToggleOn)} /&gt; {isToggleOn ? &quot;ON&quot; : &quot;OFF&quot;} &lt;/label&gt; ); }; <hr /> ```js ReactDOM.render(&lt;Toggle /&gt;, document.getElementById(&quot;root&quot;)); Renders a tooltip component. Use the useState() hook to create the show variable and initialize it to false. Render a container element that contains the tooltip element and the children passed to the component. Handle the onMouseEnter and onMouseLeave methods, by altering the value of the show variable, toggling the className of the tooltip..tooltip-container { position: relative;}.tooltip-box { position: absolute; background: rgba( 0, 0, 0, 0.7); color: #fff; padding: 5 px; border-radius: 5 px; top: calc( 100% + 5 px); display: none;}.tooltip-box.visible { display: block;}.tooltip-arrow { position: absolute; top: -10 px; left: 50%; border-width: 5 px; border-style: solid; border-color: transparent transparent rgba( 0, 0, 0, 0.7) transparent;} const Tooltip = ({ children, text, ...rest }) =&gt; { const [show, setShow] = React.useState(false); return ( &lt;div className=&quot;tooltip-container&quot;&gt; &lt;div className={show ? &quot;tooltip-box visible&quot; : &quot;tooltip-box&quot;}&gt; {text} &lt;span className=&quot;tooltip-arrow&quot; /&gt; &lt;/div&gt; &lt;div onMouseEnter={() =&gt; setShow(true)} onMouseLeave={() =&gt; setShow(false)} {...rest} &gt; {children} &lt;/div&gt; &lt;/div&gt; ); }; <hr /> ```js ReactDOM.render( &lt;Tooltip text=&quot;Simple tooltip&quot;&gt; &lt;button&gt;Hover me!&lt;/button&gt; &lt;/Tooltip&gt;, document.getElementById(&quot;root&quot;) ); Renders a tree view of a JSON object or array with collapsible content. Use the value of the toggled prop to determine the initial state of the content (collapsed/expanded). Use the useState() hook to create the isToggled state variable and give it the value of the toggled prop initially. Render a <span> element and bind its onClick event to alter the component's isToggled state. Determine the appearance of the component, based on isParentToggled, isToggled, name and checking for Array.isArray() on data. For each child in data, determine if it is an object or array and recursively render a sub-tree or a text element with the appropriate style..tree-element { margin: 0 0 0 4 px; position: relative;}.tree-element.is-child { margin-left: 16 px;} div.tree-element:before { content: ""; position: absolute; top: 24 px; left: 1 px; height: calc( 100% - 48 px); border-left: 1 px solid gray;} p.tree-element { margin-left: 16 px;}.toggler { position: absolute; top: 10 px; left: 0 px; width: 0; height: 0; border-top: 4 px solid transparent; border-bottom: 4 px solid transparent; border-left: 5 px solid gray; cursor: pointer;}.toggler.closed { transform: rotate( 90 deg);}.collapsed { display: none;} const TreeView = ({ data, toggled = true, name = null, isLast = true, isChildElement = false, isParentToggled = true, }) =&gt; { const [isToggled, setIsToggled] = React.useState(toggled); const isDataArray = Array.isArray(data); return ( &lt;div className={`tree-element ${isParentToggled &amp;&amp; &quot;collapsed&quot;} ${ isChildElement &amp;&amp; &quot;is-child&quot; }`} &gt; &lt;span className={isToggled ? &quot;toggler&quot; : &quot;toggler closed&quot;} onClick={() =&gt; setIsToggled(!isToggled)} /&gt; {name ? &lt;strong&gt;&amp;nbsp;&amp;nbsp;{name}: &lt;/strong&gt; : &lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;} {isDataArray ? &quot;[&quot; : &quot;{&quot;} {!isToggled &amp;&amp; &quot;...&quot;} {Object.keys(data).map((v, i, a) =&gt; typeof data[v] === &quot;object&quot; ? ( &lt;TreeView key={`${name}-${v}-${i}`} data={data[v]} isLast={i === a.length - 1} name={isDataArray ? null : v} isChildElement isParentToggled={isParentToggled &amp;&amp; isToggled} /&gt; ) : ( &lt;p key={`${name}-${v}-${i}`} className={isToggled ? &quot;tree-element&quot; : &quot;tree-element collapsed&quot;} &gt; {isDataArray ? &quot;&quot; : &lt;strong&gt;{v}: &lt;/strong&gt;} {data[v]} {i === a.length - 1 ? &quot;&quot; : &quot;,&quot;} &lt;/p&gt; ) )} {isDataArray ? &quot;]&quot; : &quot;}&quot;} {!isLast ? &quot;,&quot; : &quot;&quot;} &lt;/div&gt; ); }; <hr /> ```js const data = { lorem: { ipsum: &quot;dolor sit&quot;, amet: { consectetur: &quot;adipiscing&quot;, elit: [ &quot;duis&quot;, &quot;vitae&quot;, { semper: &quot;orci&quot;, }, { est: &quot;sed ornare&quot;, }, &quot;etiam&quot;, [&quot;laoreet&quot;, &quot;tincidunt&quot;], [&quot;vestibulum&quot;, &quot;ante&quot;], ], }, ipsum: &quot;primis&quot;, }, }; ReactDOM.render( &lt;TreeView data={data} name=&quot;data&quot; /&gt;, document.getElementById(&quot;root&quot;) ); Renders an uncontrolled <input> element that uses a callback function to inform its parent about value updates. Use the defaultValue passed down from the parent as the uncontrolled input field's initial value. Use the onChange event to fire the onValueChange callback and send the new value to the parent. const UncontrolledInput = ({ defaultValue, onValueChange, ...rest }) =&gt; { return ( &lt;input defaultValue={defaultValue} onChange={({ target: { value } }) =&gt; onValueChange(value)} {...rest} /&gt; ); }; ReactDOM.render( &lt;UncontrolledInput type=&quot;text&quot; placeholder=&quot;Insert some text here...&quot; onValueChange={console.log} /&gt;, document.getElementById(&quot;root&quot;) ); Handles asynchronous calls. Create a custom hook that takes a handler function, fn. Define a reducer function and an initial state for the custom hook's state. Use the useReducer() hook to initialize the state variable and the dispatch function. Define an asynchronous run function that will run the provided callback, fn, while using dispatch to update state as necessary. Return an object containing the properties of state ( value, error and loading) and the run function. const useAsync = (fn) =&gt; { const initialState = { loading: false, error: null, value: null }; const stateReducer = (_, action) =&gt; { switch (action.type) { case &quot;start&quot;: return { loading: true, error: null, value: null }; case &quot;finish&quot;: return { loading: false, error: null, value: action.value }; case &quot;error&quot;: return { loading: false, error: action.error, value: null }; } }; const [state, dispatch] = React.useReducer(stateReducer, initialState); const run = async (args = null) =&gt; { try { dispatch({ type: &quot;start&quot; }); const value = await fn(args); dispatch({ type: &quot;finish&quot;, value }); } catch (error) { dispatch({ type: &quot;error&quot;, error }); } }; return { ...state, run }; }; const RandomImage = (props) =&gt; { const imgFetch = useAsync((url) =&gt; fetch(url).then((response) =&gt; response.json()) ); return ( &lt;div&gt; &lt;button onClick={() =&gt; imgFetch.run(&quot;https://dog.ceo/api/breeds/image/random&quot;)} disabled={imgFetch.isLoading} &gt; Load image &lt;/button&gt; &lt;br /&gt; {imgFetch.loading &amp;&amp; &lt;div&gt;Loading...&lt;/div&gt;} {imgFetch.error &amp;&amp; &lt;div&gt;Error {imgFetch.error}&lt;/div&gt;} {imgFetch.value &amp;&amp; ( &lt;img src={imgFetch.value.message} alt=&quot;avatar&quot; width={400} height=&quot;auto&quot; /&gt; )} &lt;/div&gt; ); }; ReactDOM.render(&lt;RandomImage /&gt;, document.getElementById(&quot;root&quot;)); Handles the event of clicking inside the wrapped component. Create a custom hook that takes a ref and a callback to handle the 'click' event. Use the useEffect() hook to append and clean up the click event. Use the useRef() hook to create a ref for your click component and pass it to the useClickInside hook. const useClickInside = (ref, callback) =&gt; { const handleClick = (e) =&gt; { if (ref.current &amp;&amp; ref.current.contains(e.target)) { callback(); } }; React.useEffect(() =&gt; { document.addEventListener(&quot;click&quot;, handleClick); return () =&gt; { document.removeEventListener(&quot;click&quot;, handleClick); }; }); }; const ClickBox = ({ onClickInside }) =&gt; { const clickRef = React.useRef(); useClickInside(clickRef, onClickInside); return ( &lt;div className=&quot;click-box&quot; ref={clickRef} style={{ border: &quot;2px dashed orangered&quot;, height: 200, width: 400, display: &quot;flex&quot;, justifyContent: &quot;center&quot;, alignItems: &quot;center&quot;, }} &gt; &lt;p&gt;Click inside this element&lt;/p&gt; &lt;/div&gt; ); }; ReactDOM.render( &lt;ClickBox onClickInside={() =&gt; alert(&quot;click inside&quot;)} /&gt;, document.getElementById(&quot;root&quot;) ); Handles the event of clicking outside of the wrapped component. Create a custom hook that takes a ref and a callback to handle the click event. Use the useEffect() hook to append and clean up the click event. Use the useRef() hook to create a ref for your click component and pass it to the useClickOutside hook. const useClickOutside = (ref, callback) =&gt; { const handleClick = (e) =&gt; { if (ref.current &amp;&amp; !ref.current.contains(e.target)) { callback(); } }; React.useEffect(() =&gt; { document.addEventListener(&quot;click&quot;, handleClick); return () =&gt; { document.removeEventListener(&quot;click&quot;, handleClick); }; }); }; const ClickBox = ({ onClickOutside }) =&gt; { const clickRef = React.useRef(); useClickOutside(clickRef, onClickOutside); return ( &lt;div className=&quot;click-box&quot; ref={clickRef} style={{ border: &quot;2px dashed orangered&quot;, height: 200, width: 400, display: &quot;flex&quot;, justifyContent: &quot;center&quot;, alignItems: &quot;center&quot;, }} &gt; &lt;p&gt;Click out of this element&lt;/p&gt; &lt;/div&gt; ); }; ReactDOM.render( &lt;ClickBox onClickOutside={() =&gt; alert(&quot;click outside&quot;)} /&gt;, document.getElementById(&quot;root&quot;) ); Executes a callback immediately after a component is mounted. Use useEffect() with an empty array as the second argument to execute the provided callback only once when the component is mounted. Behaves like the componentDidMount() lifecycle method of class components. const useComponentDidMount = (onMountHandler) =&gt; { React.useEffect(() =&gt; { onMountHandler(); }, []); }; const Mounter = () =&gt; { useComponentDidMount(() =&gt; console.log(&quot;Component did mount&quot;)); return &lt;div&gt;Check the console!&lt;/div&gt;; }; ReactDOM.render(&lt;Mounter /&gt;, document.getElementById(&quot;root&quot;)); Executes a callback immediately before a component is unmounted and destroyed. Use useEffect() with an empty array as the second argument and return the provided callback to be executed only once before cleanup. Behaves like the componentWillUnmount() lifecycle method of class components. const useComponentWillUnmount = (onUnmountHandler) =&gt; { React.useEffect( () =&gt; () =&gt; { onUnmountHandler(); }, [] ); }; const Unmounter = () =&gt; { useComponentWillUnmount(() =&gt; console.log(&quot;Component will unmount&quot;)); return &lt;div&gt;Check the console!&lt;/div&gt;; }; ReactDOM.render(&lt;Unmounter /&gt;, document.getElementById(&quot;root&quot;)); Copies the given text to the clipboard. Use the copyToClipboard snippet to copy the text to clipboard. Use the useState() hook to initialize the copied variable. Use the useCallback() hook to create a callback for the copyToClipboard method. Use the useEffect() hook to reset the copied state variable if the text changes. Return the copied state variable and the copy callback. const useCopyToClipboard = (text) =&gt; { const copyToClipboard = (str) =&gt; { const el = document.createElement(&quot;textarea&quot;); el.value = str; el.setAttribute(&quot;readonly&quot;, &quot;&quot;); el.style.position = &quot;absolute&quot;; el.style.left = &quot;-9999px&quot;; document.body.appendChild(el); const selected = document.getSelection().rangeCount &gt; 0 ? document.getSelection().getRangeAt(0) : false; el.select(); const success = document.execCommand(&quot;copy&quot;); document.body.removeChild(el); if (selected) { document.getSelection().removeAllRanges(); document.getSelection().addRange(selected); } return success; }; const [copied, setCopied] = React.useState(false); const copy = React.useCallback(() =&gt; { if (!copied) setCopied(copyToClipboard(text)); }, [text]); React.useEffect(() =&gt; () =&gt; setCopied(false), [text]); return [copied, copy]; }; const TextCopy = (props) =&gt; { const [copied, copy] = useCopyToClipboard(&quot;Lorem ipsum&quot;); return ( &lt;div&gt; &lt;button onClick={copy}&gt;Click to copy&lt;/button&gt; &lt;span&gt;{copied &amp;&amp; &quot;Copied!&quot;}&lt;/span&gt; &lt;/div&gt; ); }; ReactDOM.render(&lt;TextCopy /&gt;, document.getElementById(&quot;root&quot;)); Debounces the given value. Create a custom hook that takes a value and a delay. Use the useState() hook to store the debounced value. Use the useEffect() hook to update the debounced value every time value is updated. Use setTimeout() to create a timeout that delays invoking the setter of the previous state variable by delay ms. Use clearTimeout() to clean up when dismounting the component. This is particularly useful when dealing with user input. const useDebounce = (value, delay) =&gt; { const [debouncedValue, setDebouncedValue] = React.useState(value); React.useEffect(() =&gt; { const handler = setTimeout(() =&gt; { setDebouncedValue(value); }, delay); return () =&gt; { clearTimeout(handler); }; }, [value]); return debouncedValue; }; const Counter = () =&gt; { const [value, setValue] = React.useState(0); const lastValue = useDebounce(value, 500); return ( &lt;div&gt; &lt;p&gt; Current: {value} - Debounced: {lastValue} &lt;/p&gt; &lt;button onClick={() =&gt; setValue(value + 1)}&gt;Increment&lt;/button&gt; &lt;/div&gt; ); }; ReactDOM.render(&lt;Counter /&gt;, document.getElementById(&quot;root&quot;)); Implements fetch in a declarative manner. Create a custom hook that takes a url and options. Use the useState() hook to initialize the response and error state variables. Use the useEffect() hook to asynchronously call fetch() and update the state variables accordingly. Return an object containing the response and error state variables. const useFetch = (url, options) =&gt; { const [response, setResponse] = React.useState(null); const [error, setError] = React.useState(null); React.useEffect(() =&gt; { const fetchData = async () =&gt; { try { const res = await fetch(url, options); const json = await res.json(); setResponse(json); } catch (error) { setError(error); } }; fetchData(); }, []); return { response, error }; }; const ImageFetch = (props) =&gt; { const res = useFetch(&quot;https://dog.ceo/api/breeds/image/random&quot;, {}); if (!res.response) { return &lt;div&gt;Loading...&lt;/div&gt;; } const imageUrl = res.response.message; return ( &lt;div&gt; &lt;img src={imageUrl} alt=&quot;avatar&quot; width={400} height=&quot;auto&quot; /&gt; &lt;/div&gt; ); }; ReactDOM.render(&lt;ImageFetch /&gt;, document.getElementById(&quot;root&quot;)); Implements setInterval in a declarative manner. Create a custom hook that takes a callback and a delay. Use the useRef() hook to create a ref for the callback function. Use a useEffect() hook to remember the latest callback whenever it changes. Use a useEffect() hook dependent on delay to set up the interval and clean up. const useInterval = (callback, delay) =&gt; { const savedCallback = React.useRef(); React.useEffect(() =&gt; { savedCallback.current = callback; }, [callback]); React.useEffect(() =&gt; { function tick() { savedCallback.current(); } if (delay !== null) { let id = setInterval(tick, delay); return () =&gt; clearInterval(id); } }, [delay]); }; const Timer = (props) =&gt; { const [seconds, setSeconds] = React.useState(0); useInterval(() =&gt; { setSeconds(seconds + 1); }, 1000); return &lt;p&gt;{seconds}&lt;/p&gt;; }; ReactDOM.render(&lt;Timer /&gt;, document.getElementById(&quot;root&quot;)); Checks if the current environment matches a given media query and returns the appropriate value. Check if window and window.matchMedia exist, return whenFalse if not (e.g. SSR environment or unsupported browser). Use window.matchMedia() to match the given query, cast its matches property to a boolean and store in a state variable, match, using the useState() hook. Use the useEffect() hook to add a listener for changes and to clean up the listeners after the hook is destroyed. Return either whenTrue or whenFalse based on the value of match. const useMediaQuery = (query, whenTrue, whenFalse) =&gt; { if (typeof window === &quot;undefined&quot; || typeof window.matchMedia === &quot;undefined&quot;) return whenFalse; const mediaQuery = window.matchMedia(query); const [match, setMatch] = React.useState(!!mediaQuery.matches); React.useEffect(() =&gt; { const handler = () =&gt; setMatch(!!mediaQuery.matches); mediaQuery.addListener(handler); return () =&gt; mediaQuery.removeListener(handler); }, []); return match ? whenTrue : whenFalse; }; const ResponsiveText = () =&gt; { const text = useMediaQuery( &quot;(max-width: 400px)&quot;, &quot;Less than 400px wide&quot;, &quot;More than 400px wide&quot; ); return &lt;span&gt;{text}&lt;/span&gt;; }; ReactDOM.render(&lt;ResponsiveText /&gt;, document.getElementById(&quot;root&quot;)); Checks if the client is online or offline. Create a function, getOnLineStatus, that uses the NavigatorOnLine web API to get the online status of the client. Use the useState() hook to create an appropriate state variable, status, and setter. Use the useEffect() hook to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting. Finally return the status state variable. const getOnLineStatus = () =&gt; typeof navigator !== &quot;undefined&quot; &amp;&amp; typeof navigator.onLine === &quot;boolean&quot; ? navigator.onLine : true; const useNavigatorOnLine = () =&gt; { const [status, setStatus] = React.useState(getOnLineStatus()); const setOnline = () =&gt; setStatus(true); const setOffline = () =&gt; setStatus(false); React.useEffect(() =&gt; { window.addEventListener(&quot;online&quot;, setOnline); window.addEventListener(&quot;offline&quot;, setOffline); return () =&gt; { window.removeEventListener(&quot;online&quot;, setOnline); window.removeEventListener(&quot;offline&quot;, setOffline); }; }, []); return status; }; const StatusIndicator = () =&gt; { const isOnline = useNavigatorOnLine(); return &lt;span&gt;You are {isOnline ? &quot;online&quot; : &quot;offline&quot;}.&lt;/span&gt;; }; ReactDOM.render(&lt;StatusIndicator /&gt;, document.getElementById(&quot;root&quot;)); Returns a stateful value, persisted in localStorage, and a function to update it. Use the useState() hook to initialize the value to defaultValue. Use the useRef() hook to create a ref that will hold the name of the value in localStorage. Use 3 instances of the useEffect() hook for initialization, value change and name change respectively. When the component is first mounted, use Storage.getItem() to update value if there's a stored value or Storage.setItem() to persist the current value. When value is updated, use Storage.setItem() to store the new value. When name is updated, use Storage.setItem() to create the new key, update the nameRef and use Storage.removeItem() to remove the previous key from localStorage. NOTE: The hook is meant for use with primitive values (i.e. not objects) and doesn't account for changes to localStorage due to other code. Both of these issues can be easily handled (e.g. JSON serialization and handling the 'storage' event). const usePersistedState = (name, defaultValue) =&gt; { const [value, setValue] = React.useState(defaultValue); const nameRef = React.useRef(name); React.useEffect(() =&gt; { try { const storedValue = localStorage.getItem(name); if (storedValue !== null) setValue(storedValue); else localStorage.setItem(name, defaultValue); } catch { setValue(defaultValue); } }, []); React.useEffect(() =&gt; { try { localStorage.setItem(nameRef.current, value); } catch {} }, [value]); React.useEffect(() =&gt; { const lastName = nameRef.current; if (name !== lastName) { try { localStorage.setItem(name, value); nameRef.current = name; localStorage.removeItem(lastName); } catch {} } }, [name]); return [value, setValue]; }; const MyComponent = ({ name }) =&gt; { const [val, setVal] = usePersistedState(name, 10); return ( &lt;input value={val} onChange={(e) =&gt; { setVal(e.target.value); }} /&gt; ); }; const MyApp = () =&gt; { const [name, setName] = React.useState(&quot;my-value&quot;); return ( &lt;&gt; &lt;MyComponent name={name} /&gt; &lt;input value={name} onChange={(e) =&gt; { setName(e.target.value); }} /&gt; &lt;/&gt; ); }; ReactDOM.render(&lt;MyApp /&gt;, document.getElementById(&quot;root&quot;)); Stores the previous state or props. Create a custom hook that takes a value. Use the useRef() hook to create a ref for the value. Use the useEffect() hook to remember the latest value. const usePrevious = (value) =&gt; { const ref = React.useRef(); React.useEffect(() =&gt; { ref.current = value; }); return ref.current; }; const Counter = () =&gt; { const [value, setValue] = React.useState(0); const lastValue = usePrevious(value); return ( &lt;div&gt; &lt;p&gt; Current: {value} - Previous: {lastValue} &lt;/p&gt; &lt;button onClick={() =&gt; setValue(value + 1)}&gt;Increment&lt;/button&gt; &lt;/div&gt; ); }; ReactDOM.render(&lt;Counter /&gt;, document.getElementById(&quot;root&quot;)); Checks if the code is running on the browser or the server. Create a custom hook that returns an appropriate object. Use typeof window, window.document and Document.createElement() to check if the code is running on the browser. Use the useState() hook to define the inBrowser state variable. Use the useEffect() hook to update the inBrowser state variable and clean up at the end. Use the useMemo() hook to memoize the return values of the custom hook. const isDOMavailable = !!( typeof window !== &quot;undefined&quot; &amp;&amp; window.document &amp;&amp; window.document.createElement ); const useSSR = () =&gt; { const [inBrowser, setInBrowser] = React.useState(isDOMavailable); React.useEffect(() =&gt; { setInBrowser(isDOMavailable); return () =&gt; { setInBrowser(false); }; }, []); const useSSRObject = React.useMemo( () =&gt; ({ isBrowser: inBrowser, isServer: !inBrowser, canUseWorkers: typeof Worker !== &quot;undefined&quot;, canUseEventListeners: inBrowser &amp;&amp; !!window.addEventListener, canUseViewport: inBrowser &amp;&amp; !!window.screen, }), [inBrowser] ); return React.useMemo( () =&gt; Object.assign(Object.values(useSSRObject), useSSRObject), [inBrowser] ); }; const SSRChecker = (props) =&gt; { let { isBrowser, isServer } = useSSR(); return &lt;p&gt;{isBrowser ? &quot;Running on browser&quot; : &quot;Running on server&quot;}&lt;/p&gt;; }; ReactDOM.render(&lt;SSRChecker /&gt;, document.getElementById(&quot;root&quot;)); Implements setTimeout in a declarative manner. Create a custom hook that takes a callback and a delay. Use the useRef() hook to create a ref for the callback function. Use the useEffect() hook to remember the latest callback. Use the useEffect() hook to set up the timeout and clean up. const useTimeout = (callback, delay) =&gt; { const savedCallback = React.useRef(); React.useEffect(() =&gt; { savedCallback.current = callback; }, [callback]); React.useEffect(() =&gt; { function tick() { savedCallback.current(); } if (delay !== null) { let id = setTimeout(tick, delay); return () =&gt; clearTimeout(id); } }, [delay]); }; const OneSecondTimer = (props) =&gt; { const [seconds, setSeconds] = React.useState(0); useTimeout(() =&gt; { setSeconds(seconds + 1); }, 1000); return &lt;p&gt;{seconds}&lt;/p&gt;; }; ReactDOM.render(&lt;OneSecondTimer /&gt;, document.getElementById(&quot;root&quot;)); Provides a boolean state variable that can be toggled between its two states. Use the useState() hook to create the value state variable and its setter. Create a function that toggles the value of the value state variable and memoize it, using the useCallback() hook. Return the value state variable and the memoized toggler function. const useToggler = (initialState) =&gt; { const [value, setValue] = React.useState(initialState); const toggleValue = React.useCallback(() =&gt; setValue((prev) =&gt; !prev), []); return [value, toggleValue]; }; const Switch = () =&gt; { const [val, toggleVal] = useToggler(false); return &lt;button onClick={toggleVal}&gt;{val ? &quot;ON&quot; : &quot;OFF&quot;}&lt;/button&gt;; }; ReactDOM.render(&lt;Switch /&gt;, document.getElementById(&quot;root&quot;)); Handles the beforeunload window event. Use the useRef() hook to create a ref for the callback function, fn. Use the useEffect() hook and EventTarget.addEventListener() to handle the 'beforeunload' (when the user is about to close the window). Use EventTarget.removeEventListener() to perform cleanup after the component is unmounted. const useUnload = (fn) =&gt; { const cb = React.useRef(fn); React.useEffect(() =&gt; { const onUnload = cb.current; window.addEventListener(&quot;beforeunload&quot;, onUnload); return () =&gt; { window.removeEventListener(&quot;beforeunload&quot;, onUnload); }; }, [cb]); }; const App = () =&gt; { useUnload((e) =&gt; { e.preventDefault(); const exit = confirm(&quot;Are you sure you want to leave?&quot;); if (exit) window.close(); }); return &lt;div&gt;Try closing the window.&lt;/div&gt;; }; ReactDOM.render(&lt;App /&gt;, document.getElementById(&quot;root&quot;));
    https://bgoonz-blog.netlify.app/images/code.png
  • Intro To React
    React In Depth React In Depth style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="react-gists" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" Random Things to Remember Using () implictly returns components. Role of index.js is to render your application. The reference to root comes from a div in the body of your public HTML file. State of a component is simply a regular JS Object. Class Components require render() method to return JSX. Functional Components directly return JSX. Class is className in React. When parsing for an integer just chain Number.parseInt("123") Use ternary operator if you want to make a conditional inside a fragment. Purpose of React.Fragment is to allow you to create groups of children without adding an extra dom element. Front-End History React makes it easier for you to make front-end elements. A front-end timeline Some noteworthy front end libraries that have been used in the past few years: 2005: Script.aculo.us 2005: Dojo 2006: YUI 2010: Knockout 2011: AngularJS 2012: Elm 2013: React (Considered the standard front-end library) React manages the creation and updating of DOM nodes in your Web page. All it does is dynamically render stuff into your DOM. What it doesn't do: Ajax Services Local Storage Provide a CSS framework React is unopinionated Just contains a few rules for developers to follow, and it just works. JSX : Javascript Extension is a language invented to help write React Applications (looks like a mixture of JS and HTML) Here is an overview of the difference between rendering out vanilla JS to create elements, and JSX: This may seem like a lot of code but when you end up building many components, it becomes nice to put each of those functions/classes into their own files to organize your code. Using tools with React React DevTools : New tool in your browser to see ow React is working in the browser create-react-app : Extensible command-line tool to help generate standard React applications. Webpack : In between tool for dealing with the extra build step involved. HMR : (Hot Module Replacement) When you make changes to your source code the changes are delivered in real-time. React Developers created something called Flux Architecture to moderate how their web page consumes and modifies data received from back-end API's. Choosing React Basically, React is super important to learn and master. React Concepts and Features There are many benefits to using React over just Vanilla JavaScript. Modularity To avoid the mess of many event listeners and template strings, React gives you the benefit of a lot of modularity. Easy to start No specials tools are needed to use Basic React. You can start working directly with createElement method in React. Declarative Programming React is declarative in nature, utilizing either it's built-in createElement method or the higher-level language known as JSX. Reusability Create elements that can be re-used over and over. One-flow of data React apps are built as a combination of parent and child components. Parents can have one or more child components, all children have parents. Data is never passed from child to the parent. Virtual DOM : React provides a Virtual DOM that acts as an agent between the real DOM and the developer to help debug, maintain, and provide general use. Due to this usage, React handles web pages much more intelligently; making it one of the speediest Front End Libraries available. ES6 Refresher Exporting one item per file Use export default statement in ES6 to export an item. ES6 CommonJS (Equivalent) Exporting multiple items per file Use just thw export keyword (without default) to export multiple items per file. ES6 (Better to export them individually like this, rather than bunching them all into an object) CommonJS (Equivalent) Importing with ES6 vs CommonJS Import statements in ES6 modules must always be at the top of the file, because all imports must occur before the rest of the file's code runs. ES6 CommonJS Unnamed default imports You can name unnamed items exported with export default any name when you import them. Just remember if you use export instead of export default then your import is already named and cannot be renamed. Aliasing imports Use as asterisk to import an entire module's contents. Keep in mind you must use an as keyword to refer to it later. You can also name identically named functions or items from different files. Browser support for ES6 Modules ES6 Modules can only be used when a JS file is specified as a module. <script type="module" src="./wallet.js"></script> You can get browser support for ES6 modules by adding module into your script tag. Notes JSX In Depth Remember that JSX is just syntactic sugar for the built in React.createElement(component, props, ...children) React Library must always be in scope from your JSX code. Use Dot Notation for JSX Type User-Defined Components Must Be Capitalized <Foo /> vs <div> Cannot use a general expression as the React element type. (Incorrect)(Corrected) Props in JSX Several ways to specify props in JSX. Javascript Expressions as Props String Literals Props Default to “True” Spread Attributes Children in JSX props.children : The content between opening and closing tag. JavaScript Expressions as Children Functions as Children props.children works like any other prop, meaning it can pass any sort of data. Booleans, Null, and Undefined Are Ignored false, null, undefined, and true are all valid children. They will not render. You can use these to conditionally render items. In this example, the component will only render if showHeader evals to True. Note that certain falsy values such as zero will still be rendered by React, you can work around this by ensuring situations like the above eval. into a boolean. In the times you want booleans to be rendered out, simply convert it into a string first. Reconciliation The Diffing Algorithm Diffing : When the state of a component changes React creates a new virtual DOM tree. Elements of Different Types Every time the root elements have different types, React tears down the old tree and builds the new tree from scratch. DOM Elements Of the Same Type When comparing two DOM elements of the same type, React keeps the same underlying DOM node and only updates the changes attributes. Component Elements Of The Same Type When components update, instances will remain the same, so that state maintains across renders. React will only update the props, to match the new element. Recursing On Children React will iterate both lists of children and generate a mutation whenever there's a difference. This is why we use keys. Makes it easier for React to match children in the original tree with children in the subsequent tree. Tradeoffs Important to remember that reconciliation algorithm is an implementation detail. Re-rendering only to apply the differences following the rules stated in the previous sections. Typechecking With PropTypes As your application grows, you can use React's typechecking to catch bugs. propTypes is a special property to run typechecking. exports range of built in validators to ensure your received data is valid. propTypes is only checked in development mode. Requiring Single Child Use PropTypes.element to specify only a single child can be passed to a component as children. Default Prop Values Use defaultProps to assign default values for props. Notes React Router Introduction React Router is the answer for rendering different components for different pages. A front-end library that allows you to control which components to display using the browser location. Client-side Routing Getting started with routing Install React Router with: npm install — save react-router-dom@⁵.1.2 Import Browser Router from package. import { BrowserRouter } from “react-router-dom”; BrowserRouter is the primary component of the router that wraps your route hierarchy. Wrap it around components. Creates a React Context that passes routing information down to all its descendant components. You can also use HashRouter, where it would generate a hash before the endpoint. Creating frontend routes React Router helps your app render specific components based on the URL. The most common component is <Route> Wrapped around another component, causing the comp. to only render if the a certain URL is matched. Props : path, component, exact, and [render] Browser Router can only have a single child component. The Browser Router wraps all routes within a parent div element. component Indicates component to render. path Indicates path to render a specific component. exact Tells route to not pattern match and only render a certain route exclusively to it's associated component. render Optional prop that takes in a function to be called. Causes extra work for React. Preferred for inline rendering of simple functional components. Difference between component and render is that component returns new JSX that be re-mounted, but render returns the JSX that will be mounted only once.// This inline rendering will work, but is unnecessarily slow. <Route path=”/hello” component={() => <h1>Hello!</h1>} /> // This is the preferred way for inline rendering. <Route path=”/hello” render={() => <h1>Hello!</h1>} /> Also useful if you need to pass in specific props to a component.// `users` to be passed as a prop: const users = { 1: { name: “Andrew” }, 2: { name: “Raymond” }, }; <Route path=”/users” render={() => <Users users={users} />} />; Route path params Your component's props can hold information about URL's parameters. Will match segments starting at : to the next /, ?, #.{...props} spreads out the router's props. props.match.params is used to access the match prop's parameters. Useful keys on the match object: isExact : boolean that tells you whether or not the URL exactly matches the path. url : the currentURL path : Route path it matched against (w/o wildcards) params : Matches for the individual wildcard segments. Navigation React Router Navigation Link, NavLink, Redirect, history props of React Router are used to help your user navigate routes. Adding links for navigation Issues on-click navigation event to a route defined in app. Usage renders an anchor tag with a correctly set href attribute. Link takes two properties: to and onClick. to : route location that points to an absolute path. onClick : clickHandler. NavLink works just like Link but has a bit of extra functionality. Adds extra styling, when the path it links to matches the current path. As it's name suggests, it is used to Nav Bars. Takes three props: activeClassName : allows you to set a CSS class name for styling. (default set to 'active') activeStyle : style object that is applied inline when it's to prop. matches the current URL. exact prop is a boolean that defaults to false; you can set it to true to apply requirement of an exact URL match. exact can also be used as a flag instead of a reg. property value. benefit of adding this is so that you don't trigger other matches. Switching between routes<Switch> : Component allows you to only render one route even if several match the current URL. You may nest as many routes as you wish but only the first match of the current URL will be rendered. Very useful if we want a default component to render if none of our routes match. DefaultComponent will only render if none of the other URLs match up.<Redirect> : Helps redirect users. Only takes a single prop: to. History History allows you to update the URL programmatically. Contains two useful methods: push : Adds a new URL to the end of the history stack. replace : Replaces the current URL on the history stack, so the back button won't take you to it. Nested Routes Why nested routes? Create routes that tunnel into main components vs getting rendered on the main page as it's own thing. What are nested routes? Alt. version using props.match As you can see above, our end URL isn't even defined until we apply those flexible values in. React Builds Build : Process of converting code into something that can actually execute or run on the target platform. In regards to React, the minimum a build should do is convert JSX to something that browsers can understand. Reviewing common terminology Linting : Process of using a tool to analyze your code to catch common errors, bugs, inconsistencies etc... Transpilation : Process of converting source code, like JS, from one version to another. Minification : Process of removing all unnecessary characters in your code. Bundling : Process of combining multiple code files into a single file. Tree Shaking : Process of removing unused or dead code from your application before it's bundled. Configuration or code? Configuration allows developers to create build tasks by declaring either JSON, XML, or YAML without explicitly writing every step in the process. Coding or Scripting simply requires code. Babel and webpack (yes, that's intentionally a lowercase 'w') Babel : Code Transpiler that allows you to use all of the latest features and syntax wihtout worrying about what browsers support what. webpack : Allows developers to use JS modules w/o requiring users to use a browser that natively supports ES modules. Create React App uses webpack and Babel under the hood to build applications. The Create React App build process What happens when you run npm start:.env variables are loaded. list of browsers to support are checked. config'd HTTP port checked for availability. application compiler is configured and created. webpack-dev-starter is started webpack-dev-starter compiles app. index.html is loaded into browser file watcher is started to watch for changes. Ejecting There is a script in Create React App called eject that allows you to 'eject' your application and expose all the hidden stuff. Preparing to deploy a React application for production Defining Env Variables Configuring the supported browsers If you specify older browsers it will affect how your code get's transpiled. Creating a production build Run npm run build to create a production build. Bundles React in production mode and optimizes the build for the best performance. Notes Introduction to React Simply a nice library that turns data into DOM. Tree Diffing : Fast comparison and patching of data by comparing the current virtual DOM and new virtual DOM - updating only the pieces that change. It's just a tree with some fancy diffing Create Element From JavaScript To DOM The React.createElement function has the following form: Type : Type of element to create, i.e. a string for an HTML element or a reference to a function or class that is a React component. Props : Object that contains data to render the element. Children : Children of the elemet, as many as you want. Creating elements Our rendering goal: There are five tags to create: One ul Two li Two a There are certain attributes we want to appear in the DOM for these tags as well: Each li has a class (or className in React) Both a ele's have href attributes Also keep in mind the parent child relationships happening between the tags. ul is the parent of both li Each li has an a element as a child Each a has a text content child Converting to virtual DOM After you set up your React.createElement, you use React.render to take the value returned from cE and a DOM node to insert into the conversion of the real DOM. JS Code => Virtual DOM => Real Dom Updates If you call React.render a second or multiple times it just checks the existing Virtual DOM and it knows which smaller areas to change. Thinking in Components Components are pieces of reusable front-end pieces. Components should be Single Responsibility Principle compliant. Create Element React.createElement Demo Can import non-local dependencies with import 'package-link' Remember when importing modules from other files you have to denote the file type in the import statement. HTML Original React Version Because class is a reserved keyword in JS, in React we can use className to assign a class to an element. Remember the data that goes into createElement: element type, data to pass into the element, and then children. props : Properties; To handle certain values that are initially undefined, we can use defaultProps. You can change in the devTools Network tab the internet speed to check for values that may be undefined to hangle with defaultProps. If we fetch multiple pieces of data, we can render many things by using map. You need to assign a unique key to each of the clues. We need to keep track of them individually so that React can easily refer to a specific one if there is an issue. clue => { key:clue.id, ...clue } Note: JSX is preferred over React.createElement; Notes from Hello Programmer Exercise When you import modules from websites they must have CORs activated. These import statements, import global variables. When we want to move our code into production we need to change the imports into the production minified versions. While we will never actually be creating full apps with just React.createElement => it is the enginer that is running under the hood! Introduction to JSX JSX : Javascript Extension, a new language created by React developers to have an easier way of interacting with the React API. How to use JSX We will use babel to convert version of modern JS into an older version of JS. React Create Element JSX Version Keep in mind that self closing tags in React must have a forward slash to close it. Properties and Data Comments in JSX have the following syntax: Property Names: checked : Attribute of input components such as checkbox or radio, use it to set whether the component is checked or not. className : Used to specify a CSS class. dangerouslySetInnerHTML : React's equivalent of innerHTML because it is risky to cross-site scripting attacks. htmlFor : Because for is protected keyword, React elements use this instead. onChange : Event fired whenever a form field is changed. style : Accepts a JS object with camelCase properties rather than a CSS string. value : Supported by Input, Select, and TextArea components; use it to set the value of the component. Note: React uses camel-case!!! The JSX semicolon gotcha create Element equivalent We wrap what want to return in parenthesis so JS doesn't auto add semi-colons after every line and run the code incorrectly. Just remember if you decided to use the return keyword in a function to 'return some JSX', then make sure you wrap the JSX in parenthesis. npx create-react-app my-app Single line used to initiate a React application. React has a great toolchain where you can see changes live as you're editing your application. React errors will be rendered directly onto the browser window. A downside is that it installs a lot of bloat files. Examples of React create Element and JSX equivalent More Complex JSX Example Notes Using Custom CRA Templates Using a Custom Template npx create-react-app my-app --template @appacademy/simple Keep in mind that using create-react-app automatically initializes a git repository for you! App Academy custom template for creating a react app. If using the default react create project you can delete the following files: favicon.ico robots.txt logo192.png logo512.png manifest.json You can also simplify the html file into: Simplifying the src folder Remove: App.css App.test.js logo.svg serviceWorker.js setupTests.js Update the Following Files: React Class Components Class Components You can write React components using ES2015 Classes: Function Component ES2015 Version We can access props within a class component by using this.props Keep in mind Class Components are used just like function components. Setting and accessing props If we define a constructor method in our Class Component, we have to define the super method with props passed through it. Side Note: Before React used ES2015 Classes, it used React.createclass function, if you ever need to use this antiquated method make sure you install a module called create-react-class Stateful components One of the major reasons why you would choose to use a Class Component over a Function Component is to add and manage local or internal state to your component. Second of the major reasons is to be able to use a Class Component's lifecycle methods. What is state? Props are data that are provided by the consumer or caller of the component. Not meant to be changed by a component. State is data that is internal to the component. Intended to be updated or mutated. When to use state Only Use State when it is absolutely necessary If the data never changes, or if it's needed through an entire application use props instead. State is more often used when creating components that retrieve data from APIs or render forms. The general rule of thumb: If a component doesn't need to use state or lifecyle methods, it should be prioritized as a function component. Functional:Stateless || Class:Stateful Initializing state Use a class constructor method to initialize this.state object. // Application Entry Point// Class Component: RandomQuote Updating State Let's say we want to update our state with a new quote. We can set up event listeners in React similarly to how we did them before.<button type=”button” onClick={this.changeQuote}> Change Quote </button> onClick is the event listener.{this.changeQuote} is the event handler method. Our Class Component File should now look like this with the new additions: Don't modify state directly It is important to never modify your state directly! ALWAYS use this.setState method to update state. This is because when you only use this.state to re-assign, no re-rendering will occur => leaving our component out of sync. Properly updating state from the previous state In our current example, the way we have changeQuote set up leaves us with occasionally producing the same index twice in a row. One solution is to design a loop but keep in mind that state updates are handled asynchronously in React (your current value is not guaranteed to be the latest) A safe method is to pass an anonymous method to this.setState (instead of an object literal) Previous Passing w/ Anon Method Providing default values for props In our current example, we pass in a static array of predefined quotes in our constructor. The way it is set up right now leaves our list of quotes unchanged after initialization. We can make quotes more dynamic by replacing our static array with a props argument passed into super. constructor(props) { super(props); } We can now move our quotes array to our application entry point and pass it in as a prop. // Application Entry Point One thing to note about this workaround is that the caller of the component must set the quotes prop or the component will throw an error => so use defaultProps! A good safety net in case the consumer/caller doesn't provide a value for the quotes array. We can even remove it from our index.js now and an error will not be thrown. Handling Events To add an event listener to an element, just define a method to handle the event and associate that method with the element event you are listening for. Example Note that when refering the handler method in onClick we're not invoking showAlert simply just passing a reference. Preventing default behavior HTML Elements in the browser often have a lot of default behavior. I.E. Clicking on an <a> element navigates so a resource denoted by <href> property. Here is an example of where using e.preventDefault() could come in handy. The button contained within the form will end up refreshing the page before this.submitForm method can be completed. We can stick an e.preventDefault() into the actual method to get around this problem. e : Parameter that references a Synthetic Event object type. Using this in event handlers When we console log this we see the AlertButton object. If we were to write the showAlert method with a regular class method like: We would get undefined => remember that fat arrow binds to the current context! Reviewing class methods and the this keyword Let's refresh on binding. The first time we use our displayMethod call, it is called directly on the instance of the boyfriend class, which is why Momato Riruru was printed out. The second time it was called, the ref of the method is stored as a variable and method is called on that variable instead of the instance; resulting in a type error (it has lost it's context) Remember we can use the bind method to rebind context! We can refactor to get the second call working like this: const displayAgain = Ming.displayName.bind(Ming); displayAgain(); // => Now Momato Riruru will be printed out. To continue using function declarations vs fat arrow we can assign context in a constructor within a class component. Experimental Syntax : Syntax that has been proposed to add to ECMAScript but hasn't officially been added to the language specification yet. It's good to pick one approach and use it consistently, either: Class Properties & Arrow Functions Bind Method & This Keyword The SyntheticEvent object Synthetic Event Objects: Cross Browser wrappeds around the browser's native event. Includes the use of stopPropagation() and preventDefault(); Attributes of the Synthetic Event Object:Attributesboolean bubblesboolean cancelableDOMEventTarget currentTargetboolean defaultPreventednumber eventPhaseboolean isTrustedDOMEvent nativeEventvoid preventDefault()boolean isDefaultPrevented()void stopPropagation()boolean isPropagationStopped()void persist()DOMEventTarget targetnumber timeStampstring type nativeEvent : property defined in a synthetic event object that gives you access to the underlying native browser event (rarely used!) Forms in React Exercise being done in a separate file Random Notes onChange : detects when a value of an input element changes. Assigning onChange to our input fields makes our component's state update in real time during user input. Dont forget to add preventDefault onto form submissions to deal with the default behavior of the browser refreshing the page! submittedOn: new Date(), Can be added to a form, most likely will persist into a DB. Controlled Components We use the onChange event handlers on form fields to keep our component's state as the "one source of truth" Adding an onChange event handler to every single input can massively bloat your code. Try assiging it to it's own method to apply everywhere. textarea is handled differently in react: it takes in a value property to handle what the inner text will be. We can use validation libraries like validate to make our validation functions more complex. Note About Client-side vs server-side validation Server-side validation is not optional. Tech-savvy users can manipulate client-side validations. Sometimes the 'best approach' is to skip implementing validations on the client-side and rely completely on the server-side validation. Component Lifecycle Component Lifecycle is simply a way of describing the key moments in the lifetime of a component. Loading (Mounting) Updating Unloading (Unmounting) The lifecycle of a React component Each Class Component has several lifecycle methods that you can add to run code at specific times. componentDidMount : Method called after your component has been added to the component tree. componentDidUpdate : Method called after your component has been updated. componentWillUnmount : Method called just before your component is removed from the component tree. Mounting constructor method is called render method is called React updates the DOM componentDidMount is called Updating When component receives new props render method is called React updates the DOM componentDidUpdate is called When setState is called render method is called React updates the DOM componentDidUpdate is called Unmounting The moment before a class component is removed from the component tree: componentDidMount will be called. Avoiding the legacy lifecycle methods Occasionally you will encounter some deprecated lifecycle methods: UNSAFE_componentWillMount UNSAFE_componentWillReceiveProps UNSAFE_componentWillUpdate Just know they will be removed soon from React's API, peace. Using the class component lifecycle methods Exercise done in sep. directory Assorted Notes: Common Use for componentDidMount lifecycle method is for fetching data from an API.— Notes React Context You can use React Context to pass data through a component tree without having to manually thread props. Convenient way to share & update global data. Creating a Context We use React.createContext to create context. Keep in mind if you invoke this method with aruguments, those arguments will be set as default context. Adding a Provider to the App component In order to pass context over to child components we need to wrap them in a provider component. The provider component takes in a value property that points to the information that needs to be passed to the children. Setting up a Consumer Keep in mind that Context.Consumer expects a function as a child. The function has a value prop passed in from Context.Provider Notes Redux Explained JS Framework for managing the frontend state of a web application. Gives us ability to store information in an organized manner in a web app and quickly retrieve that information from anywhere in the app. Redux Client Side Data Management Controls “Frontend State” NOT Your Database NOT Component State Just used for managing Data Visual of how an app without React manages it's data. A lot of prop threading happening. Data stored in a sep. location — global data. The Anatomy of Redux Store Holds the Frontend State Provides an API for the Frontend State Action POJOs Outline Changes to Frontend State Reducers Functions Make Changes to Frontend State Where did Redux come from? There are three central philosophies of Redux: A Single Source of Truth : state is stored in a POJO State is Read Only : State is immutable, modified by dispatching actions. Changes are Made with Pure Functions : Reducers that receive the actions and return updated state are pure functions of the old state and action. When is it appropriate to use Redux? When doing a project with simpler global state requirements, it may be better to choose React's Context API over Redux. Redux offers more flexibility and support for middleware along with richer developer tools. Vocabulary State Redux is a State Manager State is all the information stored by that program at a particular point in time. Redux's main job is to store the state and make it directly available to your entire app. Store Redux stores state in a single store. Redux store is a single JS object with a couple of methods (not a class!) Methods include: getState, dispatch(action), and subscribe(listener) Actions Redux store is updated by dispatching actions Action is just a POJO that includes a mandatory type property. Contain info to update the store. We dispatch actions in response to User actions or AJAX requests. Pure Functions Redux Reducers are Pure Functions Functions are pure when their behavior depends only on it's arguments as has no side effects. Simply takes in an argument and outputs a value. Reducer Redux handles actions using reducers A function that is called each time an action is dispatched. Takes in an action and current state Required to be pure functions so their behavior is predictable. Middleware Customize response to dispatch actions by using Middleware Middleware is an optional component of Redus that allows custom responses to dispatched actions. Most common use is to dispatch async requests to a server. Time Traveling Dev Tools Redux can time travel wow Time travel refers to Redux's ability to revert to a previous state because reducers are all pure functions. Thunks Convenient format for taking async actions in Redux General concept in CS referring to a function who's primary purpose is to call another function. Most commonly used to make async API requests. Flux and Redux What is Flux? Front-end application architecutre. A pattern in which to structure an application. Unidirectional Data Flow — offers more predictability. Actions : Begins the data flow of data, simple object that contains a type; type indicates the type of change to be performed. Dispatcher : Mechanism for distributing actions to the store. Store : The entire state of the application, responsible for updating the state of your app. View : Unit of code that's responsible for rendering the user interface. Used to re-render the application when actions and changes occur. Redux Library that facilitates the implementation of Flux. Redux Three Principles Single Source of Truth State is Read-Only Only Pure Functions Change State Store Simply an object that holds the application state wrapped in an API. Three methods: getState() : Returns the store's current state. dispatch(action) : Passes an action into the store's reducer to tell it what info to update. subscribe(callback) : Registers a callback to be triggered whenever the store updates. Updating the Store Subscribing to the store Whenever a store process a dispatch(), it triggers all its subscribers. Subscribers : callbacks that can be added to the store via subscribe(). Reviewing a simple example Reducers Reducer function receives the current state and action, updates the state appropriately based on the action.type and returns the following state. You can bundles different action types and ensuing logic by using a switch/case statement. Reviewing how Array#slice works Approach that can be used to remove an element without mutating the original array. Avoiding state mutations Your reducer must always return a new object if the state changes. GOOD BAD Actions Actions are the only way to trigger changes to the store's state. Using action creators fruit is the payload key and orange is the state data Action Creators : Functions created from extrapolating the creation of an action object. Use parenthesis for implicit return value. We can now add whatever fruit we'd like. Preventing typos in action type string literals Using constant variables helps reduce simple typos in a reducer's case clauses. Debugging Arrow Functions It is important to learn how to use debugger statements with arrow functions to effectively debug Redux cycle. Understanding the limitations of implicit return values You must use explicit return statement arrow function to use a debugger. React Router Introduction Now that you know how to render components in a React app, how do you handle rendering different components for different website pages? React Router is the answer! Think of how you have created server-side routes in Express. Take the following URL and server-side route. Notice how the /users/:userId path corresponds with the http://localhost:3000/users/2 URL to render a specific HTML page. In the default React setup, you lose the ability to create routes in the same manner as in Express. This is what React Router aims to solve! React Router is a frontend routing library that allows you to control which components to display using the browser location. A user can also copy and paste a URL and email it to a friend or link to it from their own website. When you finish this article, you should be able to use the following from the react-router-dom library:<BrowserRouter> to provide your application access to the react-router-dom library; and<Route> to connect specific URL paths to specific components you want rendered; and<Switch> to wrap several Route elements, rendering only one even if several match the current URL; and React Router's match prop to access route path parameters. Getting started with routing Since you are writing single page apps, you don't want to refresh the page each time you change the browser location. Instead, you want to update the browser location and your app's response using JavaScript. This is known as client-side routing. You are using React, so you will use React Router to do this. Create a simple react project template: Then install React Router: Now import BrowserRouter from react-router-dom in your entry file: BrowserRouter BrowserRouter is the primary component of the router that wraps your route hierarchy. It creates a React context that passes routing information down to all its descendent components. For example, if you want to give <App> and all its children components access to React Router, you would wrap <App> like so: Now you can route the rendering of certain components to certain URLs (i.e https://www.website.com/profile). HashRouter Alternatively, you could import and use HashRouter from react-router-dom. Links for applications that use <HashRouter> would look like https://www.website.com/#/profile (with an # between the domain and path). You'll focus on using the <BrowserRouter>. Creating frontend routes React Router helps your React application render specific components based on the URL. The React Router component you'll use most often is <Route>. The <Route> component is used to wrap another component, causing that component to only be rendered if a certain URL is matched. The behavior of the <Route> component is controlled by the following props: path, component, exact, and render (optional). Create a simple Users component that returns <h1>This is the users index!</h1>. Now let's refactor your index.js file so that you can create your routes within the component: Note that BrowserRouter can only have a single child component, so the snippet above wraps all routes within parent a <div> element. Now let's create some routes! component Begin with the component prop. This prop takes a reference to the component to be rendered. Let's render your App component: Now you'll need to connect a path to the component! path The wrapped component will only be rendered when the path is matched. The path matches the URL when it matches some initial portion of the URL. For example, a path of / would match both of the following URLs: / and /users. (Because /users begins with a / it matches the path /) Take a moment to navigate to http://localhost:3000/users to see how both the App component and Users component are rendering. exact If this exact flag is set, the path will only match when it exactly matches the URL. Then browsing to the /users path would no longer match / and only the Users component will be rendered (instead of both the App component and Users component). render This is an optional prop that takes in a function to be called. The function will be called when the path matches. The function's return value is rendered. You could also define a functional component inside the component prop, but this results in extra, unnecessary work for React. The render prop is preferred for inline rendering of simple functional components. The difference between using component and render is that component returns new JSX to be re-mounted every time the route renders, while render simply returns to JSX what will be mounted once and re-rendered. For any given route, you should only use either the component prop, or the render prop. If both are supplied, only the component prop will be used. It can be helpful to use render instead of component in your <Route> when you need to pass props into the rendered component. For example, imagine that you needed to pass the users object as a prop to your Users component. Then you could pass in props from Root to Users by returning the Users component like so: As a reminder, BrowserRouter can only have a single child component. That's why you have wrapped all your routes within parent a <div> element. With this Root component, you will always render the <h1>Hi, I'm Root!</h1>, regardless of the path. Because of the first <Route>, you will only render the App component if the path exactly matches /. Because of the second <Route>, you will only render the Users component if the path matches /users. Route path params A component's props can also hold information about a URL's parameters. The router will match route segments starting at : up to the next /, ?, or #. Those matched values are then passed to components via their props. Such segments are wildcard values that make up your route parameters. For example, take the route below: The router would break down the full /users/:userId/photos path to two parts: /users, :userId. The Profile component's props would have access to the :userId part of the http://localhost:3000/users/:userId/photos URL through the props with router parameter information. You would access the the match prop's parameters (props.match.params). If you are using the render prop of the Route component, make sure to spread the props back into the component if you want it to know about the "match" parameters. The params object would then have a property of userId which would hold the value of the :userId wildcard value. Let's render the userId parameter in a user profile component. Take a moment to create a Profile.js file with the following code: Notice how it uses the match prop to access the :userId parameter from the URL. You can use this wildcard to make and AJAX call to fetch the user information from the database and render the return data in the Profile component. Recall that your Profile component was rendered at the path /users/:userId. Thus you can use your userId parameters from match.params to fetch a specific user: Match Now that you've seen your React Router's match prop in action, let's go over more about route props! React Router passes information to the components as route props, accessible to all components with access to the React Router. The three props it makes available are location, match and history. You've learned about props.match.params, but now let's review the other properties of the match prop! This is an object that contains important information about how the current URL matches the route path. Here are some of the more useful keys on the match object: isExact: a boolean that tells you whether or not the URL exactly matches the path url: the current URL path: the route path it matched against (without wildcards filled in) params: the matches for the individual wildcard segments, nested under their names When you use React Router, the browser location and history are a part of the state of your app. You can store information about which component should be displayed, which user profile you are currently viewing, or any other piece of state, in the browser location. You can then access that information from anywhere your Router props are passed to in your app. Now that you've learned about parameters and route props, let's revisit your Root component to add an exact flag to your /users route so that it does not render with your /users/:userId route. Your component should look something like this: What you learned In this article, you learned how to: Use components from the React Router library; and Create routes to render specific components; and Manage the order of rendered routes; and Use the exact flag to ensure that a specific path renders a specific component; and Use the React Router match prop to access Router params. React Router Navigation Now that you know how to create front-end routes with React Router, you'll need to implement a way for your users to navigate the routes! This is what using React Router's Link, NavLink, Redirect, and history prop can help you do. In this article, you'll be working off of the demo project you built in the React Router Intro reading. When you finish this article, you should be able to use the following components from the react-router-dom library:<Link> or <NavLink> to create links with absolute paths to routes in your application (like "/users/1"); and,<Redirect> to redirect a user to another path (i.e. a login page when the user is not logged in); and React Router's history prop to update a browser's URL programmatically. Adding links for navigation React Router's <Link> is one way to simplify navigation around your app. It issues an on-click navigation event to a route defined in your app's router. Using <Link> renders an anchor tag with a correctly set href attribute. Link To use it, update your imports from the react-router-dom package to include Link: Note that <Link> can take two props: to and onClick. The to prop is a route location description that points to an absolute path, (i.e. /users). Add the following Link components in your index.js file above your routes: The onClick prop is just like any other JSX click handler. You can write a function that takes in an event and handles it. Add the following Link before your routes and the following click handler function within your Root component: Now, test your routes and links! If you inspect the page, you'll see that your links are now rendered as <a> elements. Notice that clicking the App with click handler link logs a message in your console while directing your browser to render the App component. NavLink The <NavLink> works just like a <Link>, but with a little extra functionality. It has the ability to add extra styling when the path it links to matches the current path. This makes it an ideal choice for a navigation bar, hence the name. This styling can be controlled by three extra props: activeClassName, activeStyle, and exact. To begin using NavLink, update your imports from the react-router-dom package: The activeClassName prop of the NavLink component allows you to set a CSS class name for styling the NavLink when its route is active. By default, the activeClassName is already set to active. This means that you simply need to add an .active class to your CSS file to add active styling to your link. A NavLink will be active if its to prop path matches the current URL. Let's change your “Users”, “Hello”, and “Andrew's Profile” links to be different colors and have a larger font size when active. For example, this is what the rendered HTML <a> tag would look like when when the browser is navigated to the / path or the /users path: Import NavLink into your index.js file and take a moment to update all your Link elements to NavLink elements. Set an activeClassName prop to an active class. Add the following .active class to your index.css file: Test your styled links! Notice how the App and App with click handler links are always bolded. This is because all of your links include the / path, meaning that the link to / will be active when browsing to /users and /users/1 because of how users and users/1 are both prefaced by a /. The activeStyle prop is a style object that will be applied inline to the NavLink when its to prop matches the current URL. Add the following activeStyle to your App link and comment out the .active class in your CSS file. The following html is rendered when at the / path: Notice how your App with click handler is not bolded anymore. This is because the default active class being applied does not have any CSS stylings set to the class. Uncomment your .active class in your CSS file to bring back bolding to this NavLink. The exact prop is a boolean that defaults to false. If set to true, then the activeStyle and activeClassName props will only be applied when the current URL exactly matches the to prop. Update your App and App with click handler links with an exact prop set. Just like in your routes, you can use the exact flag instead of exact={true}. Now your App and App with click handler links will only be bolded when you have navigated precisely to the / path. Switching between routes You came across styling issues when the /users and /users/1 paths matched the / path. Routing can have this issue as well. This is why you need to control the switching between routes. React Router's <Switch> component allows you to only render one <Route> even if several match the current URL. You can nest as many Routes as you wish between the opening and closing Switch tags, but only the first one that matches the current URL will be rendered. This is particularly useful if you want a default component that will only render if none of our other routes match. View the example below. Without the Switch, DefaultComponent would always render. Since there isn't set a path in the DefaultComponent route, it will simply use the default path of /. Now the DefaultComponent will only render when neither of the preceding routes match. Import Switch from react-router-dom and add <Switch> tags around your routes to take care of ordering and switching between your routes! Begin by adding the following route to the bottom of your routes to render that a 404: Page not found message: This is what your Root component should look like at this point: Now you have control over the precedence of rendered components! Try navigating to http://localhost:3000/asdf or any other route you have not defined. The <h1>404: Page not found</h1> JSX of the last <Route> will be rendered whenever the browser attempts to visit an undefined route. Redirecting users But what if you want to redirect users to a login page when they aren't logged in? The <Redirect> component from React Router helps you redirect users! The component takes only one prop: to. When it renders, it replaces the current URL with the value of its to prop. Typically you conditionally render <Redirect> to redirect the user away from some page you don't want them to visit. The example below checks whether there is a defined currentUser prop. If so, the <Route> will render the Home component. Otherwise, it will redirect the user to the /login path. Note: you will learn how to use a more flexible auth pattern — don't directly imitate this example. History You know how to redirect users with a <Redirect> component, but what if you need to redirect users programmatically? You've learned about the React Router's match prop, but now let's go over another one of the route props: history! This prop lets you update the URL programmatically. For example, suppose you want to push a new URL when the user clicks a button. It has two useful methods: push - This adds a new URL to the end of the history stack. That means that clicking the back button will take the browser to the previous URL. Note that pushing the same URL multiple times in a row will have no effect; the URL will still only show up on the stack once. In development mode, pushing the same URL twice in a row will generate a console warning. This warning is disabled in production mode. replace - This replaces the current URL on the history stack, so the back button won't take you to it. For example: What you learned In this article, you learned how to: Create navigation links for your route paths; and Redirect users through using the <Redirect> component; and Update a browser's URL programmatically by using React Router's history prop. React Router Nested Routes Now you know how to create front-end routes and add navigation with React Router. When initializing Express projects, you declare static routes. Static routes are routes that are declared when an application is initialized. When using React Router in your application's initialization, you can declare dynamic routes. React Router introduces dynamic routing, where your routes are created as your application is rendering. This allows you to create nested routes within components! In this article, let's dive into nested routes! When you finish the article, you should: Describe what nested routes are; and Be able to use React Router to create and navigate nested routes; and Know how to use the React Router match prop to generate links and routes. Why nested routes? Let's begin with why you might need nested routes. As you remember, you are using React to create a single-page application. This means that you'll be organizing your application into different components and sub-components. For example, imagine creating a simple front-end application with three main pages: a home welcome page (path of /), a users index page (path of /users), and user profile pages (path of /users/:userId). Now imagine if every user had links to separate posts and photos pages. You can create those routes and links within the user profile component, instead of creating the routes and links where the main routes are defined. What are nested routes? Now let's dive into a user profile component to understand what are nested routes! Imagine you have a route in your application's entry file to each user's profile like so: This means that upon navigating to http://localhost:3000/users/1, you would render the following Profile component and the userId parameter within props.match.params would have the value of "1". Since this route is not created until the Profile component is rendered, you are dynamically creating your nested /users/:userId/posts and /users/:userId/photos routes. Remember that your match prop also has other helpful properties. You can use match.url instead of /users/${id} in your profile links. You can also use match.path instead of /users/:userId in your profile routes. Remember that you can destructure url, path, and params from your match prop! In tomorrow's project, you'll build a rainbow of routes as well as define nested routes. In the future, you may choose to implement nested routes to keep your application's routes organized within related components. What you learned In this article, you learned: What nested routes are; and About creating and navigating nested routes with React Router; and How to use the React Router props to generate nested links and routes. React Builds A “build” is the process of converting code into something that can actually execute or run on the target platform. A “front-end build” is a process of preparing a front-end or client-side application for the browser. With React applications, that means (at a minimum) converting JSX to something that browsers can actually understand. When using Create React App, the build process is automatically configured to do that and a lot more. When you finish this article, you should be able to: Describe what front-end builds are and why they're needed; Describe at a high level what happens in a Create React App when you run npm start; and Prepare to deploy a React application into a production environment. Understanding front-end builds The need for front-end builds predates React. Over the years, developers have found it helpful to extend the lowest common denominator version of JavaScript and CSS that they could use. Sometimes developers extend JavaScript and CSS with something like TypeScript or Sass. Using these non-standard languages and syntaxes require you to use a build process to convert your code into standard JavaScript and CSS that can actually run in the browser. Browser-based applications also require a fair amount of optimization to deliver the best, or at least acceptable, experience to end users. Front-end build processes could be configured to lint code, run unit tests, optimize images, minify and bundle code, and more — all automatically at the press of a button (i.e. running a command at the terminal). JavaScript versions and the growth of front-end builds Developers are generally an impatient lot. When new features are added to JavaScript, we don't like to wait for browsers to widely support those features before we start to use them in our code. And we really don't like when we have to support older, legacy versions of browsers. In recent years, JavaScript has been updated on a yearly basis and browser vendors do a decent job of updating their browsers to support the new features as they're added to the language. Years ago though, there was an infamous delay between versions 5 and 6 of JavaScript. It took years before ES6 (or ES2015 as it eventually was renamed to) to officially be completed and even longer before browsers supported all of its features. In the period of time before ES2015 was broadly supported by browsers, developers used front-end builds to convert or transpile ES2015 features and syntax to an older version of the language that was more broadly supported by browsers (typically ES5). The transpilation from ES2015/ES6 down to ES5 was one of the major drivers for developers to add front-end builds to their client-side projects. Reviewing common terminology When learning about front-end or React builds, you'll encounter a lot of terminology that you may or may not be familiar with. Here's some of the terminology that you'll likely encounter: Linting is process of using a tool to analyze your code to catch common programming errors, bugs, stylistic inconsistencies, and suspicious coding patterns. ESLint is a popular JavaScript linting tool. Transpilation is the process of converting source code, like JavaScript, from one version to another version. Usually this means converting newer versions of JavaScript, ES2019 or ES2021, to a version that's more widely supported by browsers, like ES2015, or even ES5 or ES3 (if you need to support the browser that your parents or grandparents use). Minification is the process of removing all unnecessary characters in your code (e.g. white space characters, new line characters, comments) to produce an overall smaller file. Minification tools will often also rename identifers in your code (i.e. parameter and variable names) in the quest for smaller and smaller file sizes. Source maps can also be generated to allow debugging tools to cross reference between minified code and the original source code. Bundling is the process of combining multiple code files into a single file. Creating a bundle (or a handful of bundles) reduces the number of requests that a client needs to make to the server. Tree shaking is the process of removing unused (or dead) code from your application before it's bundled. Tree shaking external dependencies can sometimes have a dramatic positive impact on overall bundled file sizes. Configuration or code? Front-end build tools have come and gone over the years; sometimes very quickly, which helped bring about the phenomenon known as JavaScript fatigue. Configuration based tools allow you to create your build tasks by declaring (usually using JSON, XML, or YAML) what you want to be done, without explicitly writing every step in the process. In contrast, coding or scripting based tools allow you to, well, write code to create your build tasks. Configuration based tools can sometimes feel simpler to use while giving up some control (at least initially) while coding based tools can feel more familiar and predictable (since you're describing tasks procedurally). Every generalization is false though (including this one), so there are plenty of exceptions. Grunt is a JSON configuration based task runner that can be used to orchestrate the various tasks that make up your front-end build. Grunt was very quickly supplanted by Gulp, which allowed developers to write JavaScript to define front-end build tasks. After Gulp, the front-end tooling landscape became a bit more muddled. Some developers preferred the simplicity of using npm scripts to define build tasks while others preferred the power of configuration based bundlers like webpack. Babel and webpack (yes, that's intentionally a lowercase 'w') As front-end or client-side applications grew in complexity, developers found themselves wanting to leverage more advanced JavaScript features and newer syntax like classes, arrow functions, destructuring, async/await, etc. Using a code transpiler, like Babel, allows you to use all of the latest and greatest features and syntax without worrying about what browsers support what. Module loaders and bundlers, like webpack, also allowed developers to use JavaScript modules without requiring users to use a browser that natively supports ES modules. Also, module bundling (along with minification and tree-shaking) helps to reduce the bandwidth that's required to deliver the assets for your application to the client.[Create React App][cra] uses webpack (along with Babel) under the covers to build your React applications. Even if you're not using Create React App, webpack and Babel are still very popular choices for building React applications. Pulling back the covers (a bit) on the Create React App build process Running an application created by Create React App using npm start can feel magical. Some stuff happens in the terminal and your application opens into your default browser. Even better, when you make changes to your application, your changes will (usually) automatically appear in the browser! The Create React App build process At a high level, here's what happens when you run npm start: Environment variables are loaded (more about this in a bit); The list of browsers to support are checked (more about this too in a bit); The configured HTTP port is checked to ensure that it's available; The application compiler is configured and created; webpack-dev-server is started; webpack-dev-server compiles your application; The index.html file is loaded into the browser; and A file watcher is started to watch your files, waiting for changes. Ejecting Create React App provides a script that you can run to “eject” your application from the Create React App tooling. When you eject your application, all of the hidden stuff is exposed so that you can review and customize it. The need to customize Create React App rarely happens. Also, don't eject an actual project as it's a one-way trip! Once a Create React App project has been ejected, there's no going back (though you could always undo the ejection process by reverting to an earlier commit if you're using source control). To eject your application from Create React App, run the command npm run eject. You'll be prompted if you want to continue; type "y" to continue with the ejection process. Once the ejection process has completed, you can review the files that were previously hidden from you. In the package.json file, you'll see the following npm scripts: You can open the ./scripts/start.js file to see the code that's executed when you run npm start. If you're curious about the webpack configuration, you can open and review the ./config/webpack.config.js. Preparing to deploy a React application for production Before you deploy your application to production, you'll want to make sure that you've replaced static values in your code with environment variables and considered what browsers you need to support. Defining environment variables Create React App supports defining environment variables in an .env file. To define an environment variable, add an .env file to your project and define one or more variables that start with the prefix REACT APP\: Environment variables can be used in code like this: You can also reference environment variables in your index.html like this: Important: Environment variables are embedded into your HTML, CSS, and JavaScript bundles during the build process. Because of this, it's very important to not store any secrets, like API keys, in your environment variables as anyone can view your bundled code in the browser by inspecting your files. Configuring the supported browsers In your project's package.json file, you can see the list of targeted browsers: Adjusting these targets affect how your code will be transpiled. Specifying older browser versions will result in your code being transpiled to older versions of JavaScript in order to be compatible with the specified browser versions. The production list specifies the browsers to target when creating a production build and the development list specifics the browsers to target when running the application using npm start. The browserl.ist website can be used to see the browsers supported by your configured browserslist. Creating a production build To create a production build, run the command npm run build. The production build process bundles React in production mode and optimizes the build for the best performance. When the command completes, you'll find your production ready files in the build folder. Now your application is ready to be deployed! For more information about how to deploy a Create React App project into production, see _[ this page]( https://facebook.github.io/create-react-app/docs/deployment) in the official documentation._ What you learned In this article, you learned how to: Describe what front-end builds are and why they're needed; Describe at a high level what happens in a Create React App when you run npm start; and Prepare to deploy a React application into a production environment. React Router Documentation Now that you've had an introduction to React Router, feel free to explore the official documentation to learn more! As you become a full-fledged software engineer, remember that documentation is your friend. You can take a brief overview for now, as the documentation might include a lot of information at first. The more you learn about React, the more you should revisit the official documentation and learn! Setting up React Router React Router Quick Start HashRouter BrowserRouter Routes and Links Route Link NavLink Switch and Redirect Switch Redirect React Router Params (ownProps) props.history props.location props.match Rainbow Routes Project Today you're going to get our first experience using React Router. The goal is to create a basic app that displays the colors of the rainbow. This rainbow, however, has something special about it — some of the colors are nested within others. Phase 0: Setup Begin by creating a new React project: Now you'll remove all the contents of your src and all the contents from your public directory to build the application architecture from scratch! After you have deleted all your files within the directories, create a new index.html file in your public folder. Use the html:5 emmet shortcut to generate an HTML template. Title your page "Rainbow Routes" and create a div with an id of root in your DOM's <body> element. Create an index.css file in your src directory with the following code. Now let's create your entry file! Create an index.js entry file in the src directory. At the top of the file, make sure to import React from the react package and ReactDOM from the react-dom package. Make sure to also import your the index.css file you just created! This will take care of styling your rainbow routes. Now you can use the ReactDOM.render() method to render a <Root /> component instead of the DOM element with an id of root. Lastly, wrap your render function with a DOMContentLoaded event listener, like so: Let's create your Root component right in your entry file! Your Root component will take care of applying your BrowserRouter to the application. Applying the BrowserRouter to your Root component allows all the child components rendering within <BrowserRouter> tags to use and access the Route, Link, and NavLink components within the react-router-dom package. Install the react-router-dom package: Now import BrowserRouter from the react-router-dom package, like so: You're going to be rendering a lot of components, so let's keep your src directory organized by creating a components directory within. Within your new ./src/components directory, create a Rainbow.js file for your Rainbow component with the following code: Your Rainbow component will act as the home page or default path (/) of your application. Import the Rainbow component into your entry file and have your Root component render <Rainbow /> wrapped within <BrowserRouter> tags, like so: Within your Rainbow component, you'll be rendering <NavLink> and <Route> components to add different navigation paths to different components. Let's create all the components you will render! Create files for the following components in your ./src/components directory: Red Blue Green Indigo Orange Violet Yellow Your Red and Blue components will look something like this: Your Green, Indigo, Orange, Violet, and Yellow components will look something like this: Now start your server and verify you can see the “Rainbow Router!” header from your Rainbow component. Currently there is no functionality. Let's fix that! Phase 1: Routes As a reminder, wrapping the Rainbow component in <BrowserRouter> tags makes the router available to all descendent React Router components. Now open the Rainbow.js file. You're going to render some of your color components from here. Ultimately you want your routes to look like this. URLComponents/Rainbow/redRainbow -> Red/red/orangeRainbow -> Red -> Orange/red/yellowRainbow -> Red -> Yellow/greenRainbow -> Green/blueRainbow -> Blue/blue/indigoRainbow -> Blue -> Indigo/violetRainbow -> Violet This means that the Red, Green, Blue, and Violet components need to render in the Rainbow component, but only when you are at the corresponding URL. You'll do this with Route components. Begin by importing the Red, Green, Blue, and Violet components into your Rainbow.js file. Then add the necessary Route components inside the div with id="rainbow" in the Rainbow component. For example to render the Red component with the /red path, you would use the following Route component: Test that your code works! Manually type in each URL you just created, and you should see the color component pop up. Remember, these are React Routes, so the paths you created will come after the /. For example, your default rainbow route will look like http://localhost:3000/ while your red route will look like http://localhost:3000/red. You want to nest the Orange and Yellow components inside the Red component, and the Indigo component inside the Blue component. Remember to import your components to use them in a Route tag. You'll have to go add the corresponding Route tags to the Red.js and Blue.js files. Make sure to use the correct nested paths, such as "/red/orange" for the orange Route. Phase 2: Links Manually navigating to our newly created routes is tiresome, so let's add functionality to take care of this process for us. React Router provides the Link and NavLink components for this purpose. Add Links to the paths /red, /green, /blue, and /violet in the Rainbow component. For example, your red link should look like When you are at blue you want to be able to get to /blue/indigo, and then back to /blue. Add the corresponding Links to the Blue component like this: Similarly, add Links to /red, /red/orange and /red/yellow to the Red component. Test all your links. Navigation is so much easier now! Phase 3: NavLinks It would be nice if our links gave us some indication of which route you were at. Fortunately, React Router has a special component for that very purpose: NavLink. NavLinks get an extra CSS class when their to prop matches the current URL. By default this class is called active. Go ahead and switch all your Links to NavLinks. If you open the app you won't see any change yet. That's because you haven't added any special styling to the active class. Go ahead and open the index.css file. Create an .active class and add the line font-weight: 700. Now your active links will be bold. Isn't that nice! The only problem is that now the Blue only link is active even when the path is /blue/indigo. That doesn't make a lot of sense. Let's add the exact flag to that link so it will only be active when its to exactly matches the current path. Now it should look like: Do the same for the Red only link. Everything should be working now. Phase 4 — Changing NavLink's Active Class You've already set up NavLink to bold the link text using the .active class in src/index.css. But what if you wanted this class to be something else? For instance, what if you want your main color links (Red, Green, Blue, Violet) to be styled differently when active than your sub-route links (Red Only, Add Orange, Add Yellow, etc.). You can set the class that React Router sets to an active NavLink by adding the activeClassName prop. For instance, when we are at a route matching the below NavLink's to prop, the component will have a class of .parent-active applied: This allows much more flexibility to style an active NavLink! Using the example above, add an activeClassName prop to each of your NavLinks in src/components/Rainbow.js. Now, add some CSS styling for that class in your src/index.css to distinguish your main and your sub-route links. Compare your work to the solution and make sure the behavior is the same. Time to celebrate! ✨ 🌈 ✨ You can also learn more about using the React Router at reacttraining.com! Exploring React Builds Project In this project, you'll use Create React App to create a simple React application. You'll experiment with some of the features that Create React App provides and deploy a production build of your application to a standalone Express application. Phase 0: Setup Begin by using the create-react-app package to create a React application: Remember that using the create-react-app command initializes your project as a Git repository. If you use the ls -a to view the hidden files in your project, you'll see the .git file. Update the App component: Wrap the <h1> element with a <div> element; and Change the <h1> element content to something like "Exploring React Builds". Phase 1: Using CSS modules You've already seen an example of using the import keyword to import a stylesheet into a module so that it'll be included in your application build. That's the technique being used to include the global index.css stylesheet: You can also leverage CSS modules in your Create React App projects. CSS Modules scope stylesheet class names so that they are unique to a specific React component. This allows you to create class names without having to worry if they might collide with class names used in another component. Add a new css-modules folder to the src folder. Within that folder, add the following files: HeadingA.js HeadingA.module.css HeadingB.js HeadingB.module.css Then update the contents of each file to the following: Notice how the .heading CSS class name is being used within each component to set the color of the <h1> element. For the HeadingA component, the color is green, and for the HeadingB component, the color is red. Using the file naming convention [name].module.css let's Create React App know that we want these stylesheets to be processed as CSS Modules. Using CSS Modules allows the .heading class name to be reused across components without any issue. To see this feature in action, update your App component to render both of your new components: Then run your application (npm start) to see "Heading A" and "Heading B" displayed respectively in green and red. If you use the browser's developer tools to inspect "Heading A", you'll see that the .heading class name has been modified so that it's unique to the HeadingA component: CSS Modules is an example of how a front-end build process can be used to modify code to enable a feature that's not natively supported by browsers. Phase 2: Using an image in a component Create React App configures webpack with support for loading images (as well as CSS, fonts, and other file types). What this means, for you as the developer, is that you can add an image file to your project, import it directly into a module, and render it in a React component. Download any image of off the Web or click here to download the below image. Then within the src folder add a new folder named image. Within that folder add a new component file named Image.js. Also add your downloaded image file to the image folder (so it's a sibling to the Image.js file). Update the contents of the Image.js file to this: You can import an image into a component using the import keyword. This tells webpack to include the image in the build. Notice that when you import an image into a module, you'll get a path to the image's location within the build. You can use this path to set the src attribute on an <img> element. Be sure to update the image import statement to the correct file name if you're using your own image! Now update the App component to import and render the Image component: If you run your application (npm start) you'll see your image displayed on the page! You can also open your browser's developer tools and view the "Sources" for the current page. If you can expand the localhost:3000 > static > media node on the left, you can see the image file that webpack copied to your build. Images in stylesheets You can also reference images in your CSS files too. Add a CSS file named Image.css to the ./src/image folder and update its contents to this: Then update the Image component to this: Now you'll see the image displayed twice on the page! Phase 3: Updating the supported browsers (and its affect on code transpilation) Earlier you learned about the browerslist setting in the package.json file and now adjusting these targets affect how your code will be transpiled: The production list specifies the browsers to target when creating a production build and the development list specifics the browsers to target when running the application using npm start. Currently, you're targeting relatively recent versions of the major browsers when creating a development build. Targeting older browser versions results in your code being transpiled to an older version of JavaScript. To experiment with this configuration option, let's add a class component to the project. Add a new folder named class-component to the src folder. Within that folder, add a file named ClassComponent.js containing the following code: Don't forget to update your App component to render the new component: Now run your application using npm start. Open your browser's developer tools and view the "Sources" for the current page. Expand the localhost:3000 > static > js node on the left and select the main.chunk.js file. Press CMD+F on macOS or CTRL+F on Windows to search the file for "Class Component". Here's what the transpiled code looks like for the ClassComponent class: Have you wondered yet why you need to use the developer tools to view the bundles generated by Create React App? Remember that when you run npm start, Create React App builds your application using _[ webpack-dev-server]( https://webpack.js.org/configuration/dev-server/). To keep things as performant as possible, the bundles generated by [ webpack-dev-server]( https://webpack.js.org/configuration/dev-server/) are stored in memory instead of writing them to the file system._ The JSX in the component's render method has been converted to JavaScript but the ClassComponent ES2015 class is left alone. This makes sense though as JSX isn't natively supported by any browser while ES2015 classes have been natively supported by browsers for awhile now. But what if you need to target a version of a browser that doesn't support ES2015 classes? You can use the “Can I use…” website to see when browsers started supporting ES2105 (or ES6) classes. Starting with version 49, Chrome natively supported classes. But imagine that you need to support Chrome going back to version 30, a version of Chrome that doesn't support classes. Change the browserslist.development property in the package.json file to this: The query chrome >= 30 specifies that you want to target Chrome version 30 or newer. The _[ browserl.ist]( https://browserl.ist/) website can be used to see the browsers supported by your configured browserslist._ Stop your application if it's currently running. Delete the ./node_modules/.cache folder and run npm start again. Then view the main.chunk.js bundle again in the developer tools: Now your ES2015 class component is being converted to a constructor function! Here's the transpiled code for reference: Luckily it's very rare that you'll need to read the code in your generated bundles. webpack, by default, is configured to generate sourcemaps. Sourcemaps are a mapping of the code in a generated file, like a bundle file, to the original source code. This gives you access to your original source code in the browser's developer tools: You can even set a breakpoint in your source within the developer tools to stop execution on a specific line of code! Phase 4: Adding environment variables Earlier you learned that Create React App supports defining environment variables in an .env file. This gives you a convenient way to avoid hard coding values that vary across environments. Let's experiment with this feature so that you can see how the Create React App build process embeds environment variables into your HTML, CSS, and JavaScript bundles. Add an .env file to the root of your Create React App project. Define an environment variable named REACT APP TITLE: Remember that environment variables need to be prefixed with REACT APP for Create React App to process them. After defining your environment variable, you can refer to it within JSX using an expression and process.env: Environment variables can also be referred to in regular JavaScript code: You can also reference environment variables in your ./public/index.html file like this: Run your application again using npm start. Open your browser's developer tools and view the "Sources" for the current page. Expand the localhost:3000 node on the left and select (index). Notice that the text %REACT APP TITLE% within the <title> element has been converted to the text literal Exploring React Builds: If you expand the localhost:3000 > static > js node on the left and select the main.chunk.js file, you can see how the App component's JSX has been converted to JavaScript: Here's a closer look at the relevant React.createElement method call: Again, notice how the environment variable has been replaced with a text literal. This has important security implications for you to consider. Because environment variables are embedded into your HTML, CSS, and JavaScript bundles during the build process, it's very important to not store any secrets, like API keys, in your environment variables. Remember, anyone can view your bundled code in the browser by inspecting your files! Phase 5: Deploying a production build In the last phase of this project, let's add routing to the React application, create a production build, and deploy the build to an Express application! Adding routing To add React Router to the application, start by installing the react-router-dom npm package: Then update the App component to this code: Be sure to run and test your application to ensure that the defined routes work as expected:/ - Should display the HeadingA and HeadingB components;/image - Should display the Image component; and/class-component - Should display the ClassComponent component. Creating a production build To create a production build, run the command npm run build from the root of your project. The output in the terminal should look something like this: Ignore the comments about using serve to deploy your application (i.e. npm install -g serve and serve -s build). In the next step, you'll create a simple Express application to server your React application. Serving a React application using Express Create a new folder for your Express application outside of the Create React App project folder. For example, from the root of your project, use cd .. to go up a level and then create a new folder named express-server by running the command mkdir express-server. This makes the express-server folder a sibling to your Create React App project folder. Browse into the express-server folder and initialize it to use npm (i.e. npm init -y). Then install Express by running the command npm install express@^4.0.0. App a file named app.js with the following contents: This simple Express application will: Attempt to match incoming requests to static files located in the public folder; and If a matching static file isn't found, then the ./public/index.html file will be served for all other requests. Now add a folder named public to the root of your Express project. Copy the files from the build folder in your Create React App project to the public folder in the Express application project. Then run your application using the command node app.js. Open a browser and browse to the URL http://localhost:9000/. You should see your React application served from your Express application! Be sure to click the navigation links to verify that all of your configured routes work as expected. Also, because you configured Express to serve the ./public/index.html file for any request that doesn't match a static file, you can "deep link" to any of your React application's routes: http://localhost:9000/image http://localhost:9000/class-component
    https://bgoonz-blog.netlify.app/images/kind-whale.gif
  • Web-Dev-Hub
    React Docs React: Hello World The smallest React example looks like this: ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById('root')); It displays a heading saying "Hello, world!" on the page. Try it on CodePen https://codepen.io/bgoonz/pen/wveBJBM Click the link above to open an online editor. Feel free to make some changes, and see how they affect the output. Most pages in this guide will have editable examples like this one. How to Read This Guide In this guide, we will examine the building blocks of React apps: elements and components. Once you master them, you can create complex apps from small reusable pieces. TipThis guide is designed for people who prefer learning concepts step by step. If you prefer to learn by doing, check out our practical tutorial. You might find this guide and the tutorial complementary to each other. This is the first chapter in a step-by-step guide about main React concepts. You can find a list of all its chapters in the navigation sidebar. If you're reading this from a mobile device, you can access the navigation by pressing the button in the bottom right corner of your screen. Every chapter in this guide builds on the knowledge introduced in earlier chapters. You can learn most of React by reading the "Main Concepts" guide chapters in the order they appear in the sidebar. For example, "Introducing JSX" is the next chapter after this one. Knowledge Level Assumptions React is a JavaScript library, and so we'll assume you have a basic understanding of the JavaScript language. If you don't feel very confident, we recommend going through a JavaScript tutorial to check your knowledge level and enable you to follow along this guide without getting lost. It might take you between 30 minutes and an hour, but as a result you won't have to feel like you're learning both React and JavaScript at the same time. NoteThis guide occasionally uses some newer JavaScript syntax in the examples. If you haven't worked with JavaScript in the last few years, these three points should get you most of the way. Introducing JSX Consider this variable declaration: const element = <h1>Hello, world!</h1>; This funny tag syntax is neither a string nor HTML. It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript. JSX produces React "elements". We will explore rendering them to the DOM in the next section. Below, you can find the basics of JSX necessary to get you started. Why JSX? React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display. Instead of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled units called "components" that contain both. We will come back to components in a further section, but if you're not yet comfortable putting markup in JS, this talk might convince you otherwise. React doesn't require using JSX, but most people find it helpful as a visual aid when working with UI inside the JavaScript code. It also allows React to show more useful error and warning messages. With that out of the way, let's get started! Embedding Expressions in JSX In the example below, we declare a variable called name and then use it inside JSX by wrapping it in curly braces: const name = 'Josh Perez'; const element = <h1>Hello, {name}</h1>; ReactDOM.render(element, document.getElementById('root')); You can put any valid JavaScript expression inside the curly braces in JSX. For example, 2 + 2, user.firstName, or formatName(user) are all valid JavaScript expressions. In the example below, we embed the result of calling a JavaScript function, formatName(user), into an <h1> element. function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: 'Harper', lastName: 'Perez' }; const element = <h1> Hello, {formatName(user)}! </h1>; ReactDOM.render(element, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/oNwgZgm We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of automatic semicolon insertion. JSX is an Expression Too After compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects. This means that you can use JSX inside of if statements and for loops, assign it to variables, accept it as arguments, and return it from functions: function getGreeting(user) { if (user) { return <h1>Hello, {formatName(user)}!</h1>; } return <h1>Hello, Stranger.</h1>; } Specifying Attributes with JSX You may use quotes to specify string literals as attributes: const element = <div tabIndex="0"></div>; You may also use curly braces to embed a JavaScript expression in an attribute: const element = <img src={user.avatarUrl}></img>; Don't put quotes around curly braces when embedding a JavaScript expression in an attribute. You should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute. Warning:Since JSX is closer to JavaScript than to HTML, React DOM uses camelCase property naming convention instead of HTML attribute names.For example, class becomes className in JSX, and tabindex becomes tabIndex. Specifying Children with JSX If a tag is empty, you may close it immediately with />, like XML: const element = <img src={user.avatarUrl} />; JSX tags may contain children: const element = ( <div> <h1>Hello!</h1> <h2>Good to see you here.</h2> </div> ); JSX Prevents Injection Attacks It is safe to embed user input in JSX: const title = response.potentiallyMaliciousInput; // This is safe: const element = <h1>{title}</h1>; By default, React DOM escapes any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that's not explicitly written in your application. Everything is converted to a string before being rendered. This helps prevent XSS (cross-site-scripting) attacks. JSX Represents Objects Babel compiles JSX down to React.createElement() calls. These two examples are identical: const element = <h1 className="greeting">Hello, world!</h1>; const element = React.createElement('h1', { className: 'greeting' }, 'Hello, world!'); React.createElement() performs a few checks to help you write bug-free code but essentially it creates an object like this:// Note: this structure is simplified const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } }; These objects are called "React elements". You can think of them as descriptions of what you want to see on the screen. React reads these objects and uses them to construct the DOM and keep it up to date. We will explore rendering React elements to the DOM in the next section. Tip:We recommend using the "Babel" language definition for your editor of choice so that both ES6 and JSX code is properly highlighted. Rendering Elements Elements are the smallest building blocks of React apps. An element describes what you want to see on the screen: const element = <h1>Hello, world</h1>; Unlike browser DOM elements, React elements are plain objects, and are cheap to create. React DOM takes care of updating the DOM to match the React elements. Note:One might confuse elements with a more widely known concept of "components". We will introduce components in the next section. Elements are what components are "made of", and we encourage you to read this section before jumping ahead. Rendering an Element into the DOM Let's say there is a <div> somewhere in your HTML file:<div id="root"></div> We call this a "root" DOM node because everything inside it will be managed by React DOM. Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like. To render a React element into a root DOM node, pass both to [ReactDOM.render()](<https://reactjs.org/docs/react-dom.html#render>): const element = <h1>Hello, world</h1>; ReactDOM.render(element, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/mdwyWeb?editors=0010 It displays "Hello, world" on the page. Updating the Rendered Element React elements are immutable. Once you create an element, you can't change its children or attributes. An element is like a single frame in a movie: it represents the UI at a certain point in time. With our knowledge so far, the only way to update the UI is to create a new element, and pass it to [ReactDOM.render()](<https://reactjs.org/docs/react-dom.html#render>). Consider this ticking clock example: function tick() { const element = ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {new Date().toLocaleTimeString()}.</h2>{' '} </div> ); ReactDOM.render(element, document.getElementById('root')); } setInterval(tick, 1000); Try it on CodePen https://codepen.io/bgoonz/pen/eYRmvNy?editors=0010 It calls [ReactDOM.render()](<https://reactjs.org/docs/react-dom.html#render>) every second from a [setInterval()](<https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval>) callback. Note:In practice, most React apps only call ReactDOM.render() once. In the next sections we will learn how such code gets encapsulated into stateful components.We recommend that you don't skip topics because they build on each other. React Only Updates What's Necessary React DOM compares the element and its children to the previous one, and only applies the DOM updates necessary to bring the DOM to the desired state. You can verify by inspecting the last example with the browser tools: Even though we create an element describing the whole UI tree on every tick, only the text node whose contents have changed gets updated by React DOM. In our experience, thinking about how the UI should look at any given moment, rather than how to change it over time, eliminates a whole class of bugs. Components and Props Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components. You can find a detailed component API reference here. Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen. Function and Class Components The simplest way to define a component is to write a JavaScript function: function Welcome(props) { return <h1>Hello, {props.name}</h1>; } This function is a valid React component because it accepts a single "props" (which stands for properties) object argument with data and returns a React element. We call such components "function components" because they are literally JavaScript functions. You can also use an ES6 class to define a component: class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } The above two components are equivalent from React's point of view. Function and Class components both have some additional features that we will discuss in the next sections. Rendering a Component Previously, we only encountered React elements that represent DOM tags: const element = <div />; However, elements can also represent user-defined components: const element = <Welcome name="Sara" />; When React sees an element representing a user-defined component, it passes JSX attributes and children to this component as a single object. We call this object "props". For example, this code renders "Hello, Sara" on the page: function Welcome(props) { return <h1>Hello, {props.name}</h1>; } const element = <Welcome name="Sara" />; ReactDOM.render(element, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/QWgwpjd?editors=0010 Let's recap what happens in this example: We call ReactDOM.render() with the <Welcome name="Sara" /> element. React calls the Welcome component with {name: 'Sara'} as the props. Our Welcome component returns a <h1>Hello, Sara</h1> element as the result. React DOM efficiently updates the DOM to match <h1>Hello, Sara</h1>. Note: Always start component names with a capital letter.React treats components starting with lowercase letters as DOM tags. For example, represents an HTML div tag, but represents a component and requires Welcome to be in scope.To learn more about the reasoning behind this convention, please read JSX In Depth. Composing Components Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components. For example, we can create an App component that renders Welcome many times: function Welcome(props) { return <h1>Hello, {props.name}</h1>; } function App() { return ( <div> {' '} <Welcome name="Sara" /> <Welcome name="Cahal" /> <Welcome name="Edite" />{' '} </div> ); } ReactDOM.render(<App />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/LYLEWNq?editors=0010 Typically, new React apps have a single App component at the very top. However, if you integrate React into an existing app, you might start bottom-up with a small component like Button and gradually work your way to the top of the view hierarchy. Extracting Components Don't be afraid to split components into smaller components. For example, consider this Comment component: function Comment(props) { return ( <div className="Comment"> <div className="UserInfo"> <img className="Avatar" src={props.author.avatarUrl} alt={props.author.name} /> <div className="UserInfo-name">{props.author.name}</div> </div> <div className="Comment-text">{props.text}</div> <div className="Comment-date">{formatDate(props.date)}</div> </div> ); } Try it on CodePen https://codepen.io/bgoonz/pen/PojwpzP?editors=0010 It accepts author (an object), text (a string), and date (a date) as props, and describes a comment on a social media website. This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let's extract a few components from it. First, we will extract Avatar: function Avatar(props) { return <img className="Avatar" src={props.user.avatarUrl} alt={props.user.name} />; } The Avatar doesn't need to know that it is being rendered inside a Comment. This is why we have given its prop a more generic name: user rather than author. We recommend naming props from the component's own point of view rather than the context in which it is being used. We can now simplify Comment a tiny bit: function Comment(props) { return ( <div className="Comment"> {' '} <div className="UserInfo"> {' '} <Avatar user={props.author} /> <div className="UserInfo-name"> {props.author.name}</div>{' '} </div> <div className="Comment-text"> {props.text}</div> <div className="Comment-date"> {formatDate(props.date)}</div>{' '} </div> ); } Next, we will extract a UserInfo component that renders an Avatar next to the user's name: function UserInfo(props) { return ( <div className="UserInfo"> <Avatar user={props.user} /> <div className="UserInfo-name"> {props.user.name} </div> </div> ); } This lets us simplify Comment even further: function Comment(props) { return ( <div className="Comment"> {' '} <UserInfo user={props.author} /> <div className="Comment-text"> {props.text}</div> <div className="Comment-date"> {' '} {formatDate(props.date)} </div>{' '} </div> ); } Try it on CodePen https://codepen.io/bgoonz/pen/eYRmvzV?editors=0010 Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times ( Button, Panel, Avatar), or is complex enough on its own ( App, FeedStory, Comment), it is a good candidate to be extracted to a separate component. Props are Read-Only Whether you declare a component as a function or a class, it must never modify its own props. Consider this sum function: function sum(a, b) { return a + b; } Such functions are called "pure" because they do not attempt to change their inputs, and always return the same result for the same inputs. In contrast, this function is impure because it changes its own input: function withdraw(account, amount) { account.total -= amount; } ```js React is pretty flexible but it has a single strict rule: **All React components must act like pure functions with respect to their props.** Of course, application UIs are dynamic and change over time. In the [next section](https://reactjs.org/docs/state-and-lifecycle.html), we will introduce a new concept of "state". State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule. **State and Lifecycle** ======================= This page introduces the concept of state and lifecycle in a React component. You can find a [detailed component API reference here](https://reactjs.org/docs/react-component.html). ==================================================================================================================================================================================== Consider the ticking clock example from [one of the previous sections](https://reactjs.org/docs/rendering-elements.html#updating-the-rendered-element). In [Rendering Elements](https://reactjs.org/docs/rendering-elements.html#rendering-an-element-into-the-dom), we have only learned one way to update the UI. We call `ReactDOM.render()` to change the rendered output: ```js function tick() { const element = ( <div> <h1>Hello, world!</h1> <h2>It is {new Date().toLocaleTimeString()}.</h2> </div>); ReactDOM.render( element, document.getElementById('root') );} setInterval(tick, 1000); Try it on CodePen In this section, we will learn how to make the Clock component truly reusable and encapsulated. It will set up its own timer and update itself every second. We can start by encapsulating how the clock looks: function Clock(props) { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {props.date.toLocaleTimeString()}.</h2>{' '} </div> ); } function tick() { ReactDOM.render(<Clock date={new Date()} />, document.getElementById('root')); } setInterval(tick, 1000); Try it on CodePen https://codepen.io/bgoonz/pen/powvegw?editors=0010 However, it misses a crucial requirement: the fact that the Clock sets up a timer and updates the UI every second should be an implementation detail of the Clock. Ideally we want to write this once and have the Clock update itself: ReactDOM.render(<Clock />, document.getElementById('root')); To implement this, we need to add "state" to the Clock component. State is similar to props, but it is private and fully controlled by the component. Converting a Function to a Class You can convert a function component like Clock to a class in five steps: Create an ES6 class, with the same name, that extends React.Component. Add a single empty method to it called render(). Move the body of the function into the render() method. Replace props with this.props in the render() body. Delete the remaining empty function declaration. class Clock extends React.Component { render() { return ( <div> <h1>Hello, world!</h1> <h2>It is {this.props.date.toLocaleTimeString()}.</h2> </div> ); } } Try it on CodePen https://codepen.io/bgoonz/pen/eYRmvJV?editors=0010 Clock is now defined as a class rather than a function. The render method will be called each time an update happens, but as long as we render <Clock /> into the same DOM node, only a single instance of the Clock class will be used. This lets us use additional features such as local state and lifecycle methods. Adding Local State to a Class We will move the date from props to state in three steps: Replace this.props.date with this.state.date in the render() method: class Clock extends React.Component { render() { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{' '} </div> ); } } Add a class constructor that assigns the initial this.state: class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } render() { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{' '} </div> ); } } Note how we pass props to the base constructor: constructor(props) { super(props); this.state = {date: new Date()}; } Class components should always call the base constructor with props. Remove the date prop from the <Clock /> element: ReactDOM.render(<Clock />, document.getElementById('root')); We will later add the timer code back to the component itself. The result looks like this: class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } render() { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{' '} </div> ); } } ReactDOM.render(<Clock />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/oNwgZbV?editors=0010 Next, we'll make the Clock set up its own timer and update itself every second. Adding Lifecycle Methods to a Class In applications with many components, it's very important to free up resources taken by the components when they are destroyed. We want to set up a timer whenever the Clock is rendered to the DOM for the first time. This is called "mounting" in React. We also want to clear that timer whenever the DOM produced by the Clock is removed. This is called "unmounting" in React. We can declare special methods on the component class to run some code when a component mounts and unmounts: class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } componentDidMount() {} componentWillUnmount() {} render() { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{' '} </div> ); } } These methods are called "lifecycle methods". The componentDidMount() method runs after the component output has been rendered to the DOM. This is a good place to set up a timer: componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000 ); } Note how we save the timer ID right on this ( this.timerID). While this.props is set up by React itself and this.state has a special meaning, you are free to add additional fields to the class manually if you need to store something that doesn't participate in the data flow (like a timer ID). We will tear down the timer in the componentWillUnmount() lifecycle method: componentWillUnmount() { clearInterval(this.timerID); } Finally, we will implement a method called tick() that the Clock component will run every second. It will use this.setState() to schedule updates to the component local state: class Clock extends React.Component { constructor(props) { super(props); this.state = { date: new Date() }; } componentDidMount() { this.timerID = setInterval(() => this.tick(), 1000); } componentWillUnmount() { clearInterval(this.timerID); } tick() { this.setState({ date: new Date() }); } render() { return ( <div> {' '} <h1>Hello, world!</h1> <h2>It is {this.state.date.toLocaleTimeString()}.</h2>{' '} </div> ); } } ReactDOM.render(<Clock />, document.getElementById('root')); Try it on CodePen Now the clock ticks every second. Let's quickly recap what's going on and the order in which the methods are called: When <Clock /> is passed to ReactDOM.render(), React calls the constructor of the Clock component. Since Clock needs to display the current time, it initializes this.state with an object including the current time. We will later update this state. React then calls the Clock component's render() method. This is how React learns what should be displayed on the screen. React then updates the DOM to match the Clock's render output. When the Clock output is inserted in the DOM, React calls the componentDidMount() lifecycle method. Inside it, the Clock component asks the browser to set up a timer to call the component's tick() method once a second. Every second the browser calls the tick() method. Inside it, the Clock component schedules a UI update by calling setState() with an object containing the current time. Thanks to the setState() call, React knows the state has changed, and calls the render() method again to learn what should be on the screen. This time, this.state.date in the render() method will be different, and so the render output will include the updated time. React updates the DOM accordingly. If the Clock component is ever removed from the DOM, React calls the componentWillUnmount() lifecycle method so the timer is stopped. Using State Correctly There are three things you should know about setState(). Do Not Modify State Directly For example, this will not re-render a component:// Wrong this.state.comment = 'Hello'; Instead, use setState():// Correct this.setState({ comment: 'Hello' }); The only place where you can assign this.state is the constructor. State Updates May Be Asynchronous React may batch multiple setState() calls into a single update for performance. Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state. For example, this code may fail to update the counter:// Wrong this.setState({ counter: this.state.counter + this.props.increment }); To fix it, use a second form of setState() that accepts a function rather than an object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument:// Correct this.setState((state, props) => ({ counter: state.counter + props.increment })); We used an arrow function above, but it also works with regular functions:// Correct this.setState(function (state, props) { return { counter: state.counter + props.increment }; }); State Updates are Merged When you call setState(), React merges the object you provide into the current state. For example, your state may contain several independent variables: constructor(props) { super(props); this.state = { posts: [], comments: [] }; } Then you can update them independently with separate setState() calls: componentDidMount() { fetchPosts().then(response => { this.setState({ posts: response.posts }); }); fetchComments().then(response => { this.setState({ comments: response.comments }); }); } The merging is shallow, so this.setState({comments}) leaves this.state.posts intact, but completely replaces this.state.comments. The Data Flows Down Neither parent nor child components can know if a certain component is stateful or stateless, and they shouldn't care whether it is defined as a function or a class. This is why state is often called local or encapsulated. It is not accessible to any component other than the one that owns and sets it. A component may choose to pass its state down as props to its child components:<FormattedDate date={this.state.date} /> The FormattedDate component would receive the date in its props and wouldn't know whether it came from the Clock's state, from the Clock's props, or was typed by hand: function FormattedDate(props) { return <h2>It is {props.date.toLocaleTimeString()}.</h2>; } Try it on CodePen https://codepen.io/bgoonz/pen/GREgWEp?editors=0010 This is commonly called a "top-down" or "unidirectional" data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components "below" them in the tree. If you imagine a component tree as a waterfall of props, each component's state is like an additional water source that joins it at an arbitrary point but also flows down. To show that all components are truly isolated, we can create an App component that renders three <Clock> s: function App() { return ( <div> {' '} <Clock /> <Clock /> <Clock />{' '} </div> ); } ReactDOM.render(<App />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/YzQPZQK?editors=0010 Each Clock sets up its own timer and updates independently. In React apps, whether a component is stateful or stateless is considered an implementation detail of the component that may change over time. You can use stateless components inside stateful components, and vice versa. Handling Events Handling events with React elements is very similar to handling events on DOM elements. There are some syntax differences: React events are named using camelCase, rather than lowercase. With JSX you pass a function as the event handler, rather than a string. For example, the HTML:<button onclick="activateLasers()">Activate Lasers</button> is slightly different in React:<button onClick={activateLasers}> Activate Lasers</button> Another difference is that you cannot return false to prevent default behavior in React. You must call preventDefault explicitly. For example, with plain HTML, to prevent the default form behavior of submitting, you can write:<form onsubmit="console.log('You clicked submit.'); return false"> <button type="submit">Submit</button> </form> In React, this could instead be: function Form() { function handleSubmit(e) { e.preventDefault(); console.log('You clicked submit.'); } return ( <form onSubmit={handleSubmit}> {' '} <button type="submit">Submit</button>{' '} </form> ); } Here, e is a synthetic event. React defines these synthetic events according to the W3C spec, so you don't need to worry about cross-browser compatibility. React events do not work exactly the same as native events. See the [SyntheticEvent](<https://reactjs.org/docs/events.html>) reference guide to learn more. When using React, you generally don't need to call addEventListener to add listeners to a DOM element after it is created. Instead, just provide a listener when the element is initially rendered. When you define a component using an ES6 class, a common pattern is for an event handler to be a method on the class. For example, this Toggle component renders a button that lets the user toggle between "ON" and "OFF" states: class Toggle extends React.Component { constructor(props) { super(props); this.state = {isToggleOn: true}; // This binding is necessary to make `this` work in the callback this.handleClick = this.handleClick.bind(this); } handleClick() { this.setState(prevState => ({ isToggleOn: !prevState.isToggleOn })); }render() { return ( <button onClick={this.handleClick}> {this.state.isToggleOn ? 'ON' : 'OFF'} </button>); } } ReactDOM.render( <Toggle />, document.getElementById('root') ); Try it on CodePen You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called. This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without () after it, such as onClick={this.handleClick}, you should bind that method. If calling bind annoys you, there are two ways you can get around this. If you are using the experimental public class fields syntax, you can use class fields to correctly bind callbacks: class LoggingButton extends React.Component { // This syntax ensures `this` is bound within handleClick. // Warning: this is *experimental* syntax. handleClick = () => { console.log('this is:', this); }render() { return ( <button onClick={this.handleClick}> Click me </button>); } } This syntax is enabled by default in Create React App. If you aren't using class fields syntax, you can use an arrow function in the callback: class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // This syntax ensures `this` is bound within handleClick return ( <button onClick={() => this.handleClick()}> Click me </button>); } } The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the class fields syntax, to avoid this sort of performance problem. Passing Arguments to Event Handlers Inside a loop, it is common to want to pass an extra parameter to an event handler. For example, if id is the row ID, either of the following would work:<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button><button onClick={this.deleteRow.bind(this, id)}>Delete Row</button> The above two lines are equivalent, and use arrow functions and [Function.prototype.bind](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind>) respectively. In both cases, the e argument representing the React event will be passed as a second argument after the ID. With an arrow function, we have to pass it explicitly, but with bind any further arguments are automatically forwarded. Conditional Rendering In React, you can create distinct components that encapsulate behavior you need. Then, you can render only some of them, depending on the state of your application. Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like [if](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else>) or the conditional operator to create elements representing the current state, and let React update the UI to match them. Consider these two components: function UserGreeting(props) { return <h1>Welcome back!</h1>; } function GuestGreeting(props) { return <h1>Please sign up.</h1>; } We'll create a Greeting component that displays either of these components depending on whether a user is logged in: function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } ReactDOM.render( // Try changing to isLoggedIn={true}: <Greeting isLoggedIn={false} />, document.getElementById('root') ); Try it on CodePen https://codepen.io/bgoonz/pen/mdwyWmJ?editors=0011 This example renders a different greeting depending on the value of isLoggedIn prop. Element Variables You can use variables to store elements. This can help you conditionally render a part of the component while the rest of the output doesn't change. Consider these two new components representing Logout and Login buttons: function LoginButton(props) { return <button onClick={props.onClick}>Login</button>; } function LogoutButton(props) { return <button onClick={props.onClick}>Logout</button>; } In the example below, we will create a stateful component called LoginControl. It will render either <LoginButton /> or <LogoutButton /> depending on its current state. It will also render a <Greeting /> from the previous example: class LoginControl extends React.Component { constructor(props) { super(props); this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); this.state = { isLoggedIn: false }; } handleLoginClick() { this.setState({ isLoggedIn: true }); } handleLogoutClick() { this.setState({ isLoggedIn: false }); } render() { const isLoggedIn = this.state.isLoggedIn; let button; if (isLoggedIn) { button = <LogoutButton onClick={this.handleLogoutClick} />; } else { button = <LoginButton onClick={this.handleLoginClick} />; } return ( <div> {' '} <Greeting isLoggedIn={isLoggedIn} /> {button}{' '} </div> ); } } ReactDOM.render(<LoginControl />, document.getElementById('root')); Try it on CodePen While declaring a variable and using an if statement is a fine way to conditionally render a component, sometimes you might want to use a shorter syntax. There are a few ways to inline conditions in JSX, explained below. Inline If with Logical && Operator You may embed expressions in JSX by wrapping them in curly braces. This includes the JavaScript logical && operator. It can be handy for conditionally including an element: function Mailbox(props) { const unreadMessages = props.unreadMessages; return ( <div> {' '} <h1>Hello!</h1> {unreadMessages.length > 0 && <h2> You have {unreadMessages.length} unread messages. </h2>}{' '} </div> ); } const messages = ['React', 'Re: React', 'Re:Re: React']; ReactDOM.render(<Mailbox unreadMessages={messages} />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/VwWYppo?editors=0010 It works because in JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false. Therefore, if the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it. Note that returning a falsy expression will still cause the element after && to be skipped but will return the falsy expression. In the example below, <div>0</div> will be returned by the render method. render() { const count = 0; return ( <div> { count && <h1>Messages: {count}</h1>} </div>); } Inline If-Else with Conditional Operator Another method for conditionally rendering elements inline is to use the JavaScript conditional operator [condition ? true : false](<https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator>). In the example below, we use it to conditionally render a small block of text. render() { const isLoggedIn = this.state.isLoggedIn; return ( <div> The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in. </div>); } It can also be used for larger expressions although it is less obvious what's going on: render() { const isLoggedIn = this.state.isLoggedIn; return ( <div> {isLoggedIn ? <LogoutButton onClick={this.handleLogoutClick} /> : <LoginButton onClick={this.handleLoginClick} /> } </div> ); } Just like in JavaScript, it is up to you to choose an appropriate style based on what you and your team consider more readable. Also remember that whenever conditions become too complex, it might be a good time to extract a component. Preventing Component from Rendering In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return null instead of its render output. In the example below, the <WarningBanner /> is rendered depending on the value of the prop called warn. If the value of the prop is false, then the component does not render: function WarningBanner(props) { if (!props.warn) { return null; } return <div className="warning"> Warning!</div>; } class Page extends React.Component { constructor(props) { super(props); this.state = { showWarning: true }; this.handleToggleClick = this.handleToggleClick.bind(this); } handleToggleClick() { this.setState((state) => ({ showWarning: !state.showWarning })); } render() { return ( <div> {' '} <WarningBanner warn={this.state.showWarning} /> <button onClick={this.handleToggleClick}> {' '} {this.state.showWarning ? 'Hide' : 'Show'} </button>{' '} </div> ); } } ReactDOM.render(<Page />, document.getElementById('root')); Try it on CodePen Returning null from a component's render method does not affect the firing of the component's lifecycle methods. For instance componentDidUpdate will still be called. Lists and Keys First, let's review how you transform lists in JavaScript. Given the code below, we use the [map()](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map>) function to take an array of numbers and double their values. We assign the new array returned by map() to the variable doubled and log it: const numbers = [1, 2, 3, 4, 5]; const doubled = numbers.map((number) => number * 2); console.log(doubled); This code logs [2, 4, 6, 8, 10] to the console. In React, transforming arrays into lists of elements is nearly identical. Rendering Multiple Components You can build collections of elements and include them in JSX using curly braces {}. Below, we loop through the numbers array using the JavaScript [map()](<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map>) function. We return a <li> element for each item. Finally, we assign the resulting array of elements to listItems: const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li>{number}</li>); We include the entire listItems array inside a <ul> element, and render it to the DOM: ReactDOM.render(<ul>{listItems}</ul>, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/eYRmvvr?editors=0011 This code displays a bullet list of numbers between 1 and 5. Basic List Component Usually you would render lists inside a component. We can refactor the previous example into a component that accepts an array of numbers and outputs a list of elements. function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li>{number}</li>); return <ul>{listItems}</ul>; } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById('root')); When you run this code, you'll be given a warning that a key should be provided for list items. A "key" is a special string attribute you need to include when creating lists of elements. We'll discuss why it's important in the next section. Let's assign a key to our list items inside numbers.map() and fix the missing key issue. function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number}</li>); return <ul>{listItems}</ul>; } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render(<NumberList numbers={numbers} />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/yLXyMMP?editors=0011 Keys Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity: const numbers = [1, 2, 3, 4, 5]; const listItems = numbers.map((number) => <li key={number.toString()}> {number}</li>); The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys: const todoItems = todos.map((todo) => <li key={todo.id}> {todo.text}</li>); When you don't have stable IDs for rendered items, you may use the item index as a key as a last resort: const todoItems = todos.map((todo, index) => // Only do this if items have no stable IDs <li key={index}> {todo.text} </li>); We don't recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny's article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys. Here is an in-depth explanation about why keys are necessary if you're interested in learning more. Extracting Components with Keys Keys only make sense in the context of the surrounding array. For example, if you extract a ListItem component, you should keep the key on the <ListItem /> elements in the array rather than on the <li> element in the ListItem itself. Example: Incorrect Key Usage function ListItem(props) { const value = props.value; return ( // Wrong! There is no need to specify the key here: <li key={value.toString()}> {value} </li>); } function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // Wrong! The key should have been specified here: <ListItem value={number} /> ); return ( <ul> {listItems} </ul>); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('root') ); Example: Correct Key Usage function ListItem(props) { // Correct! There is no need to specify the key here: return <li>{props.value}</li>;} function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => // Correct! Key should be specified inside the array. <ListItem key={number.toString()} value={number} /> ); return ( <ul> {listItems} </ul>); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('root') ); Try it on CodePen A good rule of thumb is that elements inside the map() call need keys. Keys Must Only Be Unique Among Siblings Keys used within arrays should be unique among their siblings. However, they don't need to be globally unique. We can use the same keys when we produce two different arrays: function Blog(props) { const sidebar = ( <ul> {' '} {props.posts.map((post) => ( <li key={post.id}> {post.title}</li> ))} </ul> ); const content = props.posts.map((post) => ( <div key={post.id}> {' '} <h3>{post.title}</h3> <p>{post.content}</p>{' '} </div> )); return ( <div> {' '} {sidebar} <hr /> {content}{' '} </div> ); } const posts = [ { id: 1, title: 'Hello World', content: 'Welcome to learning React!' }, { id: 2, title: 'Installation', content: 'You can install React from npm.' } ]; ReactDOM.render(<Blog posts={posts} />, document.getElementById('root')); Try it on CodePen https://codepen.io/bgoonz/pen/mdwyWWy?editors=0010 Keys serve as a hint to React but they don't get passed to your components. If you need the same value in your component, pass it explicitly as a prop with a different name: const content = posts.map((post) => <Post key={post.id} id={post.id} title={post.title} />); With the example above, the Post component can read props.id, but not props.key. Embedding map() in JSX In the examples above we declared a separate listItems variable and included it in JSX: function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <ListItem key={number.toString()} value={number} />); return <ul> {listItems}</ul>; } JSX allows embedding any expression in curly braces so we could inline the map() result: function NumberList(props) { const numbers = props.numbers; return ( <ul> {' '} {numbers.map((number) => ( <ListItem key={number.toString()} value={number} /> ))}{' '} </ul> ); } Try it on CodePen https://codepen.io/bgoonz/pen/JjJoWEw?editors=0010 Sometimes this results in clearer code, but this style can also be abused. Like in JavaScript, it is up to you to decide whether it is worth extracting a variable for readability. Keep in mind that if the map() body is too nested, it might be a good time to extract a component. Forms HTML form elements work a bit differently from other DOM elements in React, because form elements naturally keep some internal state. For example, this form in plain HTML accepts a single name:<form> <label> Name: <input type="text" name="name" /> </label> <input type="submit" value="Submit" /> </form> This form has the default HTML form behavior of browsing to a new page when the user submits the form. If you want this behavior in React, it just works. But in most cases, it's convenient to have a JavaScript function that handles the submission of the form and has access to the data that the user entered into the form. The standard way to achieve this is with a technique called "controlled components". Controlled Components In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input. In React, mutable state is typically kept in the state property of components, and only updated with [setState()](<https://reactjs.org/docs/react-component.html#setstate>). We can combine the two by making the React state be the "single source of truth". Then the React component that renders a form also controls what happens in that form on subsequent user input. An input form element whose value is controlled by React in this way is called a "controlled component". For example, if we want to make the previous example log the name when it is submitted, we can write the form as a controlled component: class NameForm extends React.Component { constructor(props) { super(props); this.state = { value: '' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { alert('A name was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> {' '} <label> {' '} Name: <input type="text" value={this.state.value} onChange={this.handleChange} />{' '} </label> <input type="submit" value="Submit" />{' '} </form> ); } } Try it on CodePen https://codepen.io/bgoonz/pen/rNwayjv?editors=0010 Since the value attribute is set on our form element, the displayed value will always be this.state.value, making the React state the source of truth. Since handleChange runs on every keystroke to update the React state, the displayed value will update as the user types. With a controlled component, the input's value is always driven by the React state. While this means you have to type a bit more code, you can now pass the value to other UI elements too, or reset it from other event handlers. The textarea Tag In HTML, a <textarea> element defines its text by its children:<textarea>Hello there, this is some text in a text area</textarea> In React, a <textarea> uses a value attribute instead. This way, a form using a <textarea> can be written very similarly to a form that uses a single-line input: class EssayForm extends React.Component { constructor(props) { super(props); this.state = { value: 'Please write an essay about your favorite DOM element.' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { alert('An essay was submitted: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> {' '} <label> {' '} Essay: <textarea value={this.state.value} onChange={this.handleChange} />{' '} </label> <input type="submit" value="Submit" />{' '} </form> ); } } Notice that this.state.value is initialized in the constructor, so that the text area starts off with some text in it. The select Tag In HTML, <select> creates a drop-down list. For example, this HTML creates a drop-down list of flavors:<select><option value="grapefruit">Grapefruit</option><option value="lime">Lime</option><option selected value="coconut">Coconut</option><option value="mango">Mango</option></select> Note that the Coconut option is initially selected, because of the selected attribute. React, instead of using this selected attribute, uses a value attribute on the root select tag. This is more convenient in a controlled component because you only need to update it in one place. For example: class FlavorForm extends React.Component { constructor(props) { super(props); this.state = { value: 'coconut' }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { alert('Your favorite flavor is: ' + this.state.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> {' '} <label> {' '} Pick your favorite flavor: <select value={this.state.value} onChange={this.handleChange}> {' '} <option value="grapefruit">Grapefruit</option> <option value="lime">Lime</option> <option value="coconut">Coconut</option> <option value="mango"> Mango </option>{' '} </select>{' '} </label> <input type="submit" value="Submit" />{' '} </form> ); } } Try it on CodePen Overall, this makes it so that <input type="text">, <textarea>, and <select> all work very similarly - they all accept a value attribute that you can use to implement a controlled component. NoteYou can pass an array into the value attribute, allowing you to select multiple options in a select tag:<select multiple={true} value={['B', 'C']}> The file input Tag In HTML, an <input type="file"> lets the user choose one or more files from their device storage to be uploaded to a server or manipulated by JavaScript via the File API.<input type="file" /> Because its value is read-only, it is an uncontrolled component in React. It is discussed together with other uncontrolled components later in the documentation. Handling Multiple Inputs When you need to handle multiple controlled input elements, you can add a name attribute to each element and let the handler function choose what to do based on the value of event.target.name. For example: class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2 }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(event) { const target = event.target; const value = target.type === 'checkbox' ? target.checked : target.value; const name = target.name; this.setState({ [name]: value }); } render() { return ( <form> {' '} <label> {' '} Is going: <input name="isGoing" type="checkbox" checked={this.state.isGoing} onChange={this.handleInputChange} />{' '} </label> <br /> <label> {' '} Number of guests: <input name="numberOfGuests" type="number" value={this.state.numberOfGuests} onChange={this.handleInputChange} />{' '} </label>{' '} </form> ); } } Try it on CodePen Note how we used the ES6 computed property name syntax to update the state key corresponding to the given input name: this.setState({ [name]: value }); It is equivalent to this ES5 code: var partialState = {}; partialState[name] = value; this.setState(partialState); Also, since setState() automatically merges a partial state into the current state, we only needed to call it with the changed parts. Controlled Input Null Value Specifying the value prop on a controlled component prevents the user from changing the input unless you desire so. If you've specified a value but the input is still editable, you may have accidentally set value to undefined or null. The following code demonstrates this. (The input is locked at first but becomes editable after a short delay.) ReactDOM.render(<input value="hi" />, mountNode); setTimeout(function () { ReactDOM.render(<input value={null} />, mountNode); }, 1000); Alternatives to Controlled Components It can sometimes be tedious to use controlled components, because you need to write an event handler for every way your data can change and pipe all of the input state through a React component. This can become particularly annoying when you are converting a preexisting codebase to React, or integrating a React application with a non-React library. In these situations, you might want to check out uncontrolled components, an alternative technique for implementing input forms. Fully-Fledged Solutions If you're looking for a complete solution including validation, keeping track of the visited fields, and handling form submission, Formik is one of the popular choices. However, it is built on the same principles of controlled components and managing state --- so don't neglect to learn them. Lifting State Up Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let's see how this works in action. In this section, we will create a temperature calculator that calculates whether the water would boil at a given temperature. We will start with a component called BoilingVerdict. It accepts the celsius temperature as a prop, and prints whether it is enough to boil the water: function BoilingVerdict(props) { if (props.celsius >= 100) { return <p>The water would boil.</p>; } return <p>The water would not boil.</p>; } Next, we will create a component called Calculator. It renders an <input> that lets you enter the temperature, and keeps its value in this.state.temperature. Additionally, it renders the BoilingVerdict for the current input value. class Calculator extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { temperature: '' }; } handleChange(e) { this.setState({ temperature: e.target.value }); } render() { const temperature = this.state.temperature; return ( <fieldset> {' '} <legend>Enter temperature in Celsius:</legend> <input value={temperature} onChange={this.handleChange} /> <BoilingVerdict celsius={parseFloat(temperature)} />{' '} </fieldset> ); } } Try it on CodePen https://codepen.io/bgoonz/pen/zYzxZoL?editors=0010 Adding a Second Input Our new requirement is that, in addition to a Celsius input, we provide a Fahrenheit input, and they are kept in sync. We can start by extracting a TemperatureInput component from Calculator. We will add a new scale prop to it that can either be "c" or "f": const scaleNames = { c: 'Celsius', f: 'Fahrenheit' }; class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { temperature: '' }; } handleChange(e) { this.setState({ temperature: e.target.value }); } render() { const temperature = this.state.temperature; const scale = this.props.scale; return ( <fieldset> {' '} <legend>Enter temperature in {scaleNames[scale]}:</legend> <input value={temperature} onChange={this.handleChange} />{' '} </fieldset> ); } } We can now change the Calculator to render two separate temperature inputs: class Calculator extends React.Component { render() { return ( <div> {' '} <TemperatureInput scale="c" /> <TemperatureInput scale="f" />{' '} </div> ); } } Try it on CodePen https://codepen.io/bgoonz/pen/QWgwpGv?editors=0010 We have two inputs now, but when you enter the temperature in one of them, the other doesn't update. This contradicts our requirement: we want to keep them in sync. We also can't display the BoilingVerdict from Calculator. The Calculator doesn't know the current temperature because it is hidden inside the TemperatureInput. Writing Conversion Functions First, we will write two functions to convert from Celsius to Fahrenheit and back: function toCelsius(fahrenheit) { return ((fahrenheit - 32) * 5) / 9; } function toFahrenheit(celsius) { return (celsius * 9) / 5 + 32; } These two functions convert numbers. We will write another function that takes a string temperature and a converter function as arguments and returns a string. We will use it to calculate the value of one input based on the other input. It returns an empty string on an invalid temperature, and it keeps the output rounded to the third decimal place: function tryConvert(temperature, convert) { const input = parseFloat(temperature); if (Number.isNaN(input)) { return ''; } const output = convert(input); const rounded = Math.round(output * 1000) / 1000; return rounded.toString(); } For example, tryConvert('abc', toCelsius) returns an empty string, and tryConvert('10.22', toFahrenheit) returns '50.396'. Lifting State Up Currently, both TemperatureInput components independently keep their values in the local state: class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {temperature: ''}; } handleChange(e) { this.setState({temperature: e.target.value}); } render() { const temperature = this.state.temperature; // ... However, we want these two inputs to be in sync with each other. When we update the Celsius input, the Fahrenheit input should reflect the converted temperature, and vice versa. In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called "lifting state up". We will remove the local state from the TemperatureInput and move it into the Calculator instead. If the Calculator owns the shared state, it becomes the "source of truth" for the current temperature in both inputs. It can instruct them both to have values that are consistent with each other. Since the props of both TemperatureInput components are coming from the same parent Calculator component, the two inputs will always be in sync. Let's see how this works step by step. First, we will replace this.state.temperature with this.props.temperature in the TemperatureInput component. For now, let's pretend this.props.temperature already exists, although we will need to pass it from the Calculator in the future: render() { // Before: const temperature = this.state.temperature; const temperature = this.props.temperature; // ... We know that props are read-only. When the temperature was in the local state, the TemperatureInput could just call this.setState() to change it. However, now that the temperature is coming from the parent as a prop, the TemperatureInput has no control over it. In React, this is usually solved by making a component "controlled". Just like the DOM <input> accepts both a value and an onChange prop, so can the custom TemperatureInput accept both temperature and onTemperatureChange props from its parent Calculator. Now, when the TemperatureInput wants to update its temperature, it calls this.props.onTemperatureChange: handleChange(e) { // Before: this.setState({temperature: e.target.value}); this.props.onTemperatureChange(e.target.value); // ... Note:There is no special meaning to either temperature or onTemperatureChange prop names in custom components. We could have called them anything else, like name them value and onChange which is a common convention. The onTemperatureChange prop will be provided together with the temperature prop by the parent Calculator component. It will handle the change by modifying its own local state, thus re-rendering both inputs with the new values. We will look at the new Calculator implementation very soon. Before diving into the changes in the Calculator, let's recap our changes to the TemperatureInput component. We have removed the local state from it, and instead of reading this.state.temperature, we now read this.props.temperature. Instead of calling this.setState() when we want to make a change, we now call this.props.onTemperatureChange(), which will be provided by the Calculator: class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(e) { this.props.onTemperatureChange(e.target.value); } render() { const temperature = this.props.temperature; const scale = this.props.scale; return ( <fieldset> {' '} <legend>Enter temperature in {scaleNames[scale]}:</legend> <input value={temperature} onChange={this.handleChange} />{' '} </fieldset> ); } } Now let's turn to the Calculator component. We will store the current input's temperature and scale in its local state. This is the state we "lifted up" from the inputs, and it will serve as the "source of truth" for both of them. It is the minimal representation of all the data we need to know in order to render both inputs. For example, if we enter 37 into the Celsius input, the state of the Calculator component will be:{ temperature: '37', scale: 'c' } If we later edit the Fahrenheit field to be 212, the state of the Calculator will be:{ temperature: '212', scale: 'f' } We could have stored the value of both inputs but it turns out to be unnecessary. It is enough to store the value of the most recently changed input, and the scale that it represents. We can then infer the value of the other input based on the current temperature and scale alone. The inputs stay in sync because their values are computed from the same state: class Calculator extends React.Component { constructor(props) { super(props); this.handleCelsiusChange = this.handleCelsiusChange.bind(this); this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this); this.state = {temperature: '', scale: 'c'}; } handleCelsiusChange(temperature) { this.setState({scale: 'c', temperature}); } handleFahrenheitChange(temperature) { this.setState({scale: 'f', temperature}); } render() { const scale = this.state.scale; const temperature = this.state.temperature; const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature; const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;return ( <div> <TemperatureInputscale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange} /> <TemperatureInputscale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange} /> <BoilingVerdict celsius={parseFloat(celsius)} /> </div>); } } Try it on CodePen Now, no matter which input you edit, this.state.temperature and this.state.scale in the Calculator get updated. One of the inputs gets the value as is, so any user input is preserved, and the other input value is always recalculated based on it. Let's recap what happens when you edit an input: React calls the function specified as onChange on the DOM <input>. In our case, this is the handleChange method in the TemperatureInput component. The handleChange method in the TemperatureInput component calls this.props.onTemperatureChange() with the new desired value. Its props, including onTemperatureChange, were provided by its parent component, the Calculator. When it previously rendered, the Calculator had specified that onTemperatureChange of the Celsius TemperatureInput is the Calculator's handleCelsiusChange method, and onTemperatureChange of the Fahrenheit TemperatureInput is the Calculator's handleFahrenheitChange method. So either of these two Calculator methods gets called depending on which input we edited. Inside these methods, the Calculator component asks React to re-render itself by calling this.setState() with the new input value and the current scale of the input we just edited. React calls the Calculator component's render method to learn what the UI should look like. The values of both inputs are recomputed based on the current temperature and the active scale. The temperature conversion is performed here. React calls the render methods of the individual TemperatureInput components with their new props specified by the Calculator. It learns what their UI should look like. React calls the render method of the BoilingVerdict component, passing the temperature in Celsius as its props. React DOM updates the DOM with the boiling verdict and to match the desired input values. The input we just edited receives its current value, and the other input is updated to the temperature after conversion. Every update goes through the same steps so the inputs stay in sync. Lessons Learned There should be a single "source of truth" for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the top-down data flow. Lifting state involves writing more "boilerplate" code than two-way binding approaches, but as a benefit, it takes less work to find and isolate bugs. Since any state "lives" in some component and that component alone can change it, the surface area for bugs is greatly reduced. Additionally, you can implement any custom logic to reject or transform user input. If something can be derived from either props or state, it probably shouldn't be in the state. For example, instead of storing both celsiusValue and fahrenheitValue, we store just the last edited temperature and its scale. The value of the other input can always be calculated from them in the render() method. This lets us clear or apply rounding to the other field without losing any precision in the user input. When you see something wrong in the UI, you can use React Developer Tools to inspect the props and move up the tree until you find the component responsible for updating the state. This lets you trace the bugs to their source: Composition vs Inheritance React has a powerful composition model, and we recommend using composition instead of inheritance to reuse code between components. In this section, we will consider a few problems where developers new to React often reach for inheritance, and show how we can solve them with composition. Containment Some components don't know their children ahead of time. This is especially common for components like Sidebar or Dialog that represent generic "boxes". We recommend that such components use the special children prop to pass children elements directly into their output: function FancyBorder(props) { return <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div>; } This lets other components pass arbitrary children to them by nesting the JSX: function WelcomeDialog() { return ( <FancyBorder color="blue"> {' '} <h1 className="Dialog-title"> Welcome </h1> <p className="Dialog-message"> Thank you for visiting our spacecraft! </p>{' '} </FancyBorder> ); } Try it on CodePen Anything inside the <FancyBorder> JSX tag gets passed into the FancyBorder component as a children prop. Since FancyBorder renders {props.children} inside a <div>, the passed elements appear in the final output. While this is less common, sometimes you might need multiple "holes" in a component. In such cases you may come up with your own convention instead of using children: function SplitPane(props) { return ( <div className="SplitPane"> <div className="SplitPane-left"> {props.left} </div> <div className="SplitPane-right"> {props.right} </div> </div>); } function App() { return ( <SplitPaneleft={ <Contacts /> }right={ <Chat /> } />); } Try it on CodePen React elements like <Contacts /> and <Chat /> are just objects, so you can pass them as props like any other data. This approach may remind you of "slots" in other libraries but there are no limitations on what you can pass as props in React. Specialization Sometimes we think about components as being "special cases" of other components. For example, we might say that a WelcomeDialog is a special case of Dialog. In React, this is also achieved by composition, where a more "specific" component renders a more "generic" one and configures it with props: function Dialog(props) { return ( <FancyBorder color="blue"> {' '} <h1 className="Dialog-title"> {props.title} </h1> <p className="Dialog-message"> {props.message} </p>{' '} </FancyBorder> ); } function WelcomeDialog() { return <Dialog title="Welcome" message="Thank you for visiting our spacecraft!" />; } Try it on CodePen Composition works equally well for components defined as classes: function Dialog(props) { return ( <FancyBorder color="blue"> {' '} <h1 className="Dialog-title"> {props.title}</h1> <p className="Dialog-message"> {props.message}</p> {props.children}{' '} </FancyBorder> ); } class SignUpDialog extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleSignUp = this.handleSignUp.bind(this); this.state = { login: '' }; } render() { return ( <Dialog title="Mars Exploration Program" message="How should we refer to you?"> {' '} <input value={this.state.login} onChange={this.handleChange} /> <button onClick={this.handleSignUp}> Sign Me Up! </button>{' '} </Dialog> ); } handleChange(e) { this.setState({ login: e.target.value }); } handleSignUp() { alert(`Welcome aboard, ${this.state.login}!`); } } Try it on CodePen So What About Inheritance? At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies. Props and composition give you all the flexibility you need to customize a component's look and behavior in an explicit and safe way. Remember that components may accept arbitrary props, including primitive values, React elements, or functions. If you want to reuse non-UI functionality between components, we suggest extracting it into a separate JavaScript module. The components may import it and use that function, object, or a class, without extending it. Thinking in React React is, in our opinion, the premier way to build big, fast Web apps with JavaScript. It has scaled very well for us at Facebook and Instagram. One of the many great parts of React is how it makes you think about apps as you build them. In this document, we'll walk you through the thought process of building a searchable product data table using React. Start With A Mock Imagine that we already have a JSON API and a mock from our designer. The mock looks like this: Our JSON API returns some data that looks like this:[ { category: 'Sporting Goods', price: '$49.99', stocked: true, name: 'Football' }, { category: 'Sporting Goods', price: '$9.99', stocked: true, name: 'Baseball' }, { category: 'Sporting Goods', price: '$29.99', stocked: false, name: 'Basketball' }, { category: 'Electronics', price: '$99.99', stocked: true, name: 'iPod Touch' }, { category: 'Electronics', price: '$399.99', stocked: false, name: 'iPhone 5' }, { category: 'Electronics', price: '$199.99', stocked: true, name: 'Nexus 7' } ]; Step 1: Break The UI Into A Component Hierarchy The first thing you'll want to do is to draw boxes around every component (and subcomponent) in the mock and give them all names. If you're working with a designer, they may have already done this, so go talk to them! Their Photoshop layer names may end up being the names of your React components! But how do you know what should be its own component? Use the same techniques for deciding if you should create a new function or object. One such technique is the single responsibility principle, that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents. Since you're often displaying a JSON data model to a user, you'll find that if your model was built correctly, your UI (and therefore your component structure) will map nicely. That's because UI and data models tend to adhere to the same information architecture. Separate your UI into components, where each component matches one piece of your data model. You'll see here that we have five components in our app. We've italicized the data each component represents. FilterableProductTable (orange): contains the entirety of the example SearchBar (blue): receives all user input ProductTable (green): displays and filters the data collection based on user input ProductCategoryRow (turquoise): displays a heading for each category ProductRow (red): displays a row for each product If you look at ProductTable, you'll see that the table header (containing the "Name" and "Price" labels) isn't its own component. This is a matter of preference, and there's an argument to be made either way. For this example, we left it as part of ProductTable because it is part of rendering the data collection which is ProductTable's responsibility. However, if this header grows to be complex (e.g., if we were to add affordances for sorting), it would certainly make sense to make this its own ProductTableHeader component. Now that we've identified the components in our mock, let's arrange them into a hierarchy. Components that appear within another component in the mock should appear as a child in the hierarchy: FilterableProductTable SearchBar ProductTable ProductCategoryRow ProductRow Step 2: Build A Static Version in React See the Pen Thinking In React: Step 2 on CodePen. Now that you have your component hierarchy, it's time to implement your app. The easiest way is to build a version that takes your data model and renders the UI but has no interactivity. It's best to decouple these processes because building a static version requires a lot of typing and no thinking, and adding interactivity requires a lot of thinking and not a lot of typing. We'll see why. To build a static version of your app that renders your data model, you'll want to build components that reuse other components and pass data using props. props are a way of passing data from parent to child. If you're familiar with the concept of state, don't use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don't need it. You can build top-down or bottom-up. That is, you can either start with building the components higher up in the hierarchy (i.e. starting with FilterableProductTable) or with the ones lower in it ( ProductRow). In simpler examples, it's usually easier to go top-down, and on larger projects, it's easier to go bottom-up and write tests as you build. At the end of this step, you'll have a library of reusable components that render your data model. The components will only have render() methods since this is a static version of your app. The component at the top of the hierarchy ( FilterableProductTable) will take your data model as a prop. If you make a change to your underlying data model and call ReactDOM.render() again, the UI will be updated. You can see how your UI is updated and where to make changes. React's one-way data flow (also called one-way binding) keeps everything modular and fast. Refer to the React docs if you need help executing this step. A Brief Interlude: Props vs State There are two types of "model" data in React: props and state. It's important to understand the distinction between the two; skim the official React docs if you aren't sure what the difference is. See also FAQ: What is the difference between state and props? Step 3: Identify The Minimal (but complete) Representation Of UI State To make your UI interactive, you need to be able to trigger changes to your underlying data model. React achieves this with state. To build your app correctly, you first need to think of the minimal set of mutable state that your app needs. The key here is DRY: Don't Repeat Yourself. Figure out the absolute minimal representation of the state your application needs and compute everything else you need on-demand. For example, if you're building a TODO list, keep an array of the TODO items around; don't keep a separate state variable for the count. Instead, when you want to render the TODO count, take the length of the TODO items array. Think of all the pieces of data in our example application. We have: The original list of products The search text the user has entered The value of the checkbox The filtered list of products Let's go through each one and figure out which one is state. Ask three questions about each piece of data: Is it passed in from a parent via props? If so, it probably isn't state. Does it remain unchanged over time? If so, it probably isn't state. Can you compute it based on any other state or props in your component? If so, it isn't state. The original list of products is passed in as props, so that's not state. The search text and the checkbox seem to be state since they change over time and can't be computed from anything. And finally, the filtered list of products isn't state because it can be computed by combining the original list of products with the search text and value of the checkbox. So finally, our state is: The search text the user has entered The value of the checkbox Step 4: Identify Where Your State Should Live See the Pen Thinking In React: Step 4 on CodePen. OK, so we've identified what the minimal set of app state is. Next, we need to identify which component mutates, or owns, this state. Remember: React is all about one-way data flow down the component hierarchy. It may not be immediately clear which component should own what state. This is often the most challenging part for newcomers to understand, so follow these steps to figure it out: For each piece of state in your application: Identify every component that renders something based on that state. Find a common owner component (a single component above all the components that need the state in the hierarchy). Either the common owner or another component higher up in the hierarchy should own the state. If you can't find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common owner component. Let's run through this strategy for our application: ProductTable needs to filter the product list based on state and SearchBar needs to display the search text and checked state. The common owner component is FilterableProductTable. It conceptually makes sense for the filter text and checked value to live in FilterableProductTable Cool, so we've decided that our state lives in FilterableProductTable. First, add an instance property this.state = {filterText: '', inStockOnly: false} to FilterableProductTable's constructor to reflect the initial state of your application. Then, pass filterText and inStockOnly to ProductTable and SearchBar as a prop. Finally, use these props to filter the rows in ProductTable and set the values of the form fields in SearchBar. You can start seeing how your application will behave: set filterText to "ball" and refresh your app. You'll see that the data table is updated correctly. Step 5: Add Inverse Data Flow See the Pen Thinking In React: Step 5 on CodePen. So far, we've built an app that renders correctly as a function of props and state flowing down the hierarchy. Now it's time to support data flowing the other way: the form components deep in the hierarchy need to update the state in FilterableProductTable. React makes this data flow explicit to help you understand how your program works, but it does require a little more typing than traditional two-way data binding. If you try to type or check the box in the current version of the example, you'll see that React ignores your input. This is intentional, as we've set the value prop of the input to always be equal to the state passed in from FilterableProductTable. Let's think about what we want to happen. We want to make sure that whenever the user changes the form, we update the state to reflect the user input. Since components should only update their own state, FilterableProductTable will pass callbacks to SearchBar that will fire whenever the state should be updated. We can use the onChange event on the inputs to be notified of it. The callbacks passed by FilterableProductTable will call setState(), and the app will be updated. And That's It Hopefully, this gives you an idea of how to think about building components and applications with React. While it may be a little more typing than you're used to, remember that code is read far more than it's written, and it's less difficult to read this modular, explicit code. As you start to build large libraries of components, you'll appreciate this explicitness and modularity, and with code reuse, your lines of code will start to shrink. :) Advanced Content React Component
    https://bgoonz-blog.netlify.app/images/react2-1cfd4b21.jpg
  • Web-Dev-Hub
    Introducing JSX Introducing JSX Consider this variable declaration: This funny tag syntax is neither a string nor HTML. It is called JSX, and it is a syntax extension to JavaScript. We recommend using it with React to describe what the UI should look like. JSX may remind you of a template language, but it comes with the full power of JavaScript. JSX produces React “elements”. We will explore rendering them to the DOM in the next section. Below, you can find the basics of JSX necessary to get you started. Why JSX? React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display. Instead of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled units called “components” that contain both. We will come back to components in a further section, but if you're not yet comfortable putting markup in JS, this talk might convince you otherwise. React doesn't require using JSX, but most people find it helpful as a visual aid when working with UI inside the JavaScript code. It also allows React to show more useful error and warning messages. With that out of the way, let's get started! Embedding Expressions in JSX In the example below, we declare a variable called name and then use it inside JSX by wrapping it in curly braces: You can put any valid JavaScript expression inside the curly braces in JSX. For example, 2 + 2, user.firstName, or formatName(user) are all valid JavaScript expressions. In the example below, we embed the result of calling a JavaScript function, formatName(user), into an <h1> element. Try it on CodePen We split JSX over multiple lines for readability. While it isn't required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of automatic semicolon insertion. JSX is an Expression Too After compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects. This means that you can use JSX inside of if statements and for loops, assign it to variables, accept it as arguments, and return it from functions: Specifying Attributes with JSX You may use quotes to specify string literals as attributes: You may also use curly braces to embed a JavaScript expression in an attribute: Don't put quotes around curly braces when embedding a JavaScript expression in an attribute. You should either use quotes (for string values) or curly braces (for expressions), but not both in the same attribute. Warning: Since JSX is closer to JavaScript than to HTML, React DOM uses camelCase property naming convention instead of HTML attribute names. For example, class becomes className in JSX, and tabindex becomes tabIndex. Specifying Children with JSX If a tag is empty, you may close it immediately with />, like XML: JSX tags may contain children: JSX Prevents Injection Attacks It is safe to embed user input in JSX: By default, React DOM escapes any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that's not explicitly written in your application. Everything is converted to a string before being rendered. This helps prevent XSS (cross-site-scripting) attacks. JSX Represents Objects Babel compiles JSX down to React.createElement() calls. These two examples are identical: React.createElement() performs a few checks to help you write bug-free code but essentially it creates an object like this: These objects are called “React elements”. You can think of them as descriptions of what you want to see on the screen. React reads these objects and uses them to construct the DOM and keep it up to date. We will explore rendering React elements to the DOM in the next section. Tip: We recommend using the “Babel” language definition for your editor of choice so that both ES6 and JSX code is properly highlighted.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    React Class Components Demo React Class Components Demo React Demo ex1 — A Basic React Component ex2 — A Basic React Class Component ex3 — A Class Component with State ex4 — A Class Component that Updates State ex5 — A Class Component that Iterates through State ex6 — An Example of Parent and Child Components With regards to converting an existing HTML, CSS, and JS site into React, first you'll want to think about how to break up your site into components, as well as think about what the general hierarchical component structure of your site will look like. From there, it's a simple matter of copying the relevant HTML for that component and throwing it into the render method of your component file. Any methods that are needed for that component to function properly can added onto your new component. Once you've refactored your HTML components into React components, you'll want to lay them out in the desired hierarchical structure with children components being rendered by their parents, as well as ensuring that the parent components are passing down the necessary data as props to their children components. ex.)<!-- Hello world --> <div class="awesome" style="border: 1px solid red"> <label for="name">Enter your name: </label> <input type="text" id="name" /> </div> <p>Enter your HTML here</p> Is equivalent to: let NewComponent = React.createClass({ render: function () { return ( <div> {/* Hello world */} <div className="awesome" style={{ border: '1px solid red' }}> <label htmlFor="name">Enter your name: </label> <input type="text" id="name" /> </div> <p>Enter your HTML here</p> </div> ); } }); A Basic Component Acomponent is some thing that is being rendered in the browser. It could be a button, a form with a bunch of fields in it…etc.… React doesn't place any restrictions on how large or small a component can be. You could have an entire static site encapsulated in a single React component, but that would defeat the purpose of using React. So the first thing to remember about a component is that a component must render something. If nothing is being rendered from a component, then React will throw an error. Inside of BasicComponent.js , first import React at the top of the file. Our most basic of components looks like this: import React from 'react'; const BasicComponent = () => <div>Hello World!</div>; export default BasicComponent; This is a component that simply returns a div tag with the words Hello World! inside. The last line simply exports our component so that it can be imported by another file. Notice that this component looks exactly like an anonymous arrow function that we've named BasicComponent . In fact, that is literally what this is. The arrow function then is simply returning the div tag. When a component is written as a function like this one is, it is called a functional component. A Basic Class Component The above component is an example of a functional component, which is appropriate since that component is literally nothing more than a function that returns some HTML. Functional components are great when all you want a component to do is to render some stuff. Components can also be written as classes (although this paradigm is becoming outdated and you should strive to write your components functionally! For this exercise, we're going to write a class component that does exactly the same thing as the functional component we just wrote. We'll again need to import React at the top of the file, but we'll also need to add a little something. Our import statement will look like this: import React, { Component } from 'react'; So, in addition to importing React, we're also importing the base Component class that is included in the React library. React lets you define components as classes or functions. Components defined as classes currently provide more features . To define a React component class, you need to extend React.Component: class Welcome extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } } The only method you must define in a React.Component subclass is called ``. render() The render() method is the only required method in a class component. When called, it should examine this.props and this.state and return one of the following types: React elements. Typically created via JSX. For example, <div /> and <MyComponent /> are React elements that instruct React to render a DOM node, or another user-defined component, respectively. Arrays and fragments. Let you return multiple elements from render. See the documentation on fragments for more details. Portals. Let you render children into a different DOM subtree. See the documentation on portals for more details. String and numbers. These are rendered as text nodes in the DOM. Booleans or null. Render nothing. (Mostly exists to support return test && <Child /> pattern, where test is boolean.) The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it's invoked, and it does not directly interact with the browser. If you need to interact with the browser, perform your work in componentDidMount() or the other lifecycle methods instead. Keeping render() pure makes components easier to think about. Note* will not be invoked if* []( https://reactjs.org/docs/react-component.html#shouldcomponentupdate) returns false. The export statement at the bottom of the file also stays, completely unchanged. Our class component will thus look like this: import React, { Component } from 'react'; class BasicClassComponent extends Component { render() { return <div>Hello World!</div>; } } export default BasicClassComponent; Notice that our BasicClassComponent inherits from the base Component class that we imported from the React library, by virtue of the 'extends' keyword. That being said, there's nothing in this minimal component that takes advantage of any of those inherited methods. All we have is a method on our component class called render that returns the same div tag. If we really were deciding between whether to use a functional component versus a class component to render a simple div tag, then the functional style is more appropriate to use. This is because class components are much better suited for handling component state and triggering events based on the component's lifecycle. The important takeaways at this point are that there are two types of components, functional and class components, and that functional components are well-suited if you're just looking to render some HTML. Class components, on the other hand, are much better suited for handling components that require more complex functionality, need to exhibit more varied behavior, and/or need to keep track of some state that may change throughout said component's lifecycle. A Class Component with Some State Component state is any dynamic data that we want the component to keep track of. For example, let's say we have a form component. This form has some input fields that we'd like users to fill out. When a user types characters into an input field, how is that input persisted from the point of view of our form component? The answer is by using component state! There are a few important concepts regarding component state, such as how to update it, pass it to another component, render it, etc. Only class components have the ability to persist state, so if at any time you realize that a component needs to keep track of some state, you know that you'll automatically need a class component instead of a functional component. It is possible to handle state with functional components but that requires the use of something called the useState() hook. Hooks were added in React 16.8; prior to this release, there was no mechanism to add state to functional components. Here's what the above component looks like as a functional component: Our class component with state will look a lot like the basic class component we just wrote, but with some exceptions: import React, { Component } from 'react'; class ClassComponentWithState extends Component { constructor() { super(); this.state = {}; } render() { return <div>Hello World!</div>; } } export default ClassComponentWithState; So far, the only new thing going on here is the constructor block. If you recall how classes in JavaScript work, classes need constructors. Additionally, if a class is extending off of another class and wants access to its parent class's methods and properties, then the super function needs to be called inside the class's constructor function. Point being, the constructor function and the call to the super function are not associated with React, they are associated with all JavaScript classes. Then there is the ``** property inside the constructor function that is set as an empty object**. We're adding a property called state to our class and setting it to an empty object. State objects in React are always just plain old objects. So why is it that the basic class component we wrote in the previous exercise had no constructor function within its body? That is because we had no need for them since all our class component was doing was rendering some HTML. The constructor is needed here because that is where we need to initialize our state object. The call to super is needed because we can't reference this inside of our constructor without a call to super first. Ok, now let's actually use this state object. One very common application of state objects in React components is to render the data being stored inside them within our component's render function. Refactoring our component class to do that: class ClassComponentWithState extends Component { constructor() { super(); this.state = { someData: 8 }; } render() { return <div>{`Here's some data to render: ${this.state.someData}`}</div>; } } export default ClassComponentWithState; We added a key-value pair to our state object inside our constructor. Then we changed the contents of the render function. Now, it's actually rendering the data that we have inside the state object. Notice that inside the div tags we're using a template string literal so that we can access the value of this.state.someData straight inside of our rendered content. With Reacts newest version, we can actually now add state to a component without explicitly defining a constructor on the class. We can refactor our class component to look like this: class ClassComponentWithState extends Component { state = { someData: 8 }; render() { return <div>{`Here's some data to render: ${this.state.someData}`}</div>; } } export default ClassComponentWithState; This new syntax is what is often referred to as 'syntactic sugar': under the hood, the React library translates this back into the old constructor code that we first started with, so that the JavaScript remains valid to the JavaScript interpreter. The clue to this is the fact that when we want to access some data from the state object, we still need to call it with this.state.someData ; changing it to just state.someData does not work. Class Component Updating State Great, so we can render some state that our component persists for us. However, we said an important use case of component state is to handle dynamic data. A single static number isn't very dynamic at all. So now let's walk through how to update component state. import React, { Component } from 'react'; class ClassComponentUpdatingState extends Component { constructor() { super(); this.state = { aNumber: 8 }; } increment = () => { this.setState({ aNumber: ++this.state.aNumber }); }; decrement = () => { this.setState({ aNumber: --this.state.aNumber }); }; render() { return ( <div> <div>{`Our number: ${this.state.aNumber}`}</div> <button onClick={this.increment}>+</button> <button onClick={this.decrement}>-</button> </div> ); } } export default ClassComponentUpdatingState; Notice that we've added two methods to our class: increment and decrement . increment and decrement are methods that we are adding to our class component. Unlike the render method, increment and decrement were not already a part of our class component. This is why increment and decrement are written as arrow functions, so that they are automatically bound to our class component. The alternative is using a declaration syntax function with the bind method to bind the context of our methods to the class component. The more interesting thing is what is going on within the bodies of these methods. Each calls the setState function. setState in fact is provided to us by React. It is the standard way to update a component's state. It's the only way you should ever update a component's state. It may seem more verbose than necessary, but there are good reasons for why you should be doing it this way. Unlike the lifecycle methods above (which React calls for you), the methods below are the methods you can call from your components. There are just two of them: setState() and forceUpdate(). setState() setState(updater, [callback]) setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses. Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately. setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall. Instead, use componentDidUpdate or a setState callback ( setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below. setState() will always lead to a re-render unless shouldComponentUpdate() returns false. If mutable objects are being used and conditional rendering logic cannot be implemented in shouldComponentUpdate(), calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders. The first argument is an updater function with the signature:(state, props) => stateChange state is a reference to the component state at the time the change is being applied. It should not be directly mutated. Instead, changes should be represented by building a new object based on the input from state and props. For instance, suppose we wanted to increment a value in state by props.step: this.setState((state, props) => { return {counter: state.counter + props.step}; }); Both state and props received by the updater function are guaranteed to be up-to-date. The output of the updater is shallowly merged with state. The second parameter to setState() is an optional callback function that will be executed once setState is completed and the component is re-rendered. Generally we recommend using componentDidUpdate() for such logic instead. You may optionally pass an object as the first argument to setState() instead of a function: setState(stateChange[, callback]) This performs a shallow merge of stateChange into the new state, e.g., to adjust a shopping cart item quantity: this.setState({quantity: 2}) This form of setState() is also asynchronous, and multiple calls during the same cycle may be batched together. For example, if you attempt to increment an item quantity more than once in the same cycle, that will result in the equivalent of: Object.assign( previousState, {quantity: state.quantity + 1}, {quantity: state.quantity + 1}, ... ) Subsequent calls will override values from previous calls in the same cycle, so the quantity will only be incremented once. If the next state depends on the current state, we recommend using the updater function form, instead: this.setState((state) => { return {quantity: state.quantity + 1}; }); So the way to use setState to update a component's state is to pass it an object with each of the state keys you wish to update, along with the updated value. In our increment method we said "I would like to update the aNumber property on my component state by adding one to it and then setting the new value as my new aNumber ". The same thing happens in our decrement method, only we're subtracting instead of adding. Then the other new concept we're running into here is how to actually call these methods we've added to our class. We added two HTML button tags within our render function, then in their respective onClick handlers, we specify the method that should be called whenever this button gets clicked. So whenever we click either of the buttons, our state gets updated appropriately and our component will re-render to show the correct value we're expecting. Class Component Iterating State Another common state pattern you'll see being used in React components is iterating over an array in our state object and rendering each array element in its own tag. This is often used in order to render lists. Additionally, we want to be able to easily update lists and have React re-render our updated list. We'll see how both of these are done and how they work together within a single component in order to create the behavior of a dynamic list. import React, { Component } from 'react'; class ClassComponentIteratingState extends Component { constructor() { super(); this.state = { ingredients: ['flour', 'eggs', 'milk', 'sugar', 'vanilla extract'], newIngredient: '' }; } handleIngredientInput = (event) => { this.setState({ newIngredient: event.target.value }); }; addIngredient = (event) => { event.preventDefault(); const ingredientsList = this.state.ingredients; ingredientsList.push(this.state.newIngredient); this.setState({ newIngredient: '', ingredients: ingredientsList }); }; render() { return ( <div> {this.state.ingredients.map((ingredient) => ( <div>{ingredient}</div> ))} <form onSubmit={this.addIngredient}> <input type="text" onChange={this.handleIngredientInput} placeholder="Add a new ingredient" value={this.state.newIngredient} /> </form> </div> ); } } export default ClassComponentIteratingState; The first change to note is that our state object now has an 'ingredients' array, and a 'newIngredient' field that has been initialized to an empty string. The ingredients array contains the elements that we'll want to render in our list. The addIngredient and handleIngredientInput methods we've added to our class receives a parameter called 'event'. This event object is part of the browser's API. When we interact with some DOM element, such as clicking on an HTML button, the function that is invoked upon that button being clicked actually receives the event object. So when we type some input into an input tag, we're able grab each character that was typed into the input field through the event object parameter. The handleIngredientInput method is what gets invoked every time the user presses a key to enter text in the input box for adding a new ingredient. Every character the user types gets persisted in the newIngredient field on the state object. We're able to grab the text in the input box using event.target.value Which holds the value of the string text that is currently in the input box. We use that to update our newIngredient string field. Breaking down the addIngredient method, we see this event.preventDefault() invocation. This is because this method will be used upon submitting a form, and it turns out that submitting a form triggers some default form behavior that we don't want to trigger when we submit the form ( namely refreshing the entire page). event.preventDefault() will prevent this default form behavior, meaning our form will only do what we want it to do when it is submitted. Next, we store a reference to this.state.ingredients in a variable called ingredientsList . So we now have a copy of the array that is stored in our state object. We want to update the copy of the ingredients array first instead of directly updating the actual array itself in state. Now we push whatever value is being stored at our newIngredient field onto the ingredientsList array so that our ingredientsList array is now more up-to-date than our this.state.ingredients array. So all we have to do now is call setState appropriately in order to update the value in our state object. Additionally, we also set the newIngredient field back to an empty string in order to clear out the input field once we submit a new ingredient. Now it's ready to accept more user input! Looking at our render function, first note the this.state.ingredients.map call. This is looping through each ingredient in our ingredients array and returning each one within its own div tag. This is a very common pattern for rendering everything inside an array. Then we have an HTML form which contains an input field. The purpose of this form is to allow a user to add new ingredients to the list. Note that we're passing our addIngredient method to the form's onSubmit handler. This means that our addIngredient method gets invoked whenever our form is submitted. Lastly, the input field has an onChange handler that invokes our handleIngredientInput method whenever there is some sort of change in the input field, namely when a user types into it. Notice that the value field in our input tag reads off of this.state.newIngredient in order to know what value to display. So when a user enters text into the input field, the onChange handler is invoked every time, which updates our this.state.newIngredient field, which the input field and then renders. Parent and Child Components A single isolated component isn't going to do us much good. The beauty of React lies in the fact that it allows us to compose modular components together. Let's start off with the component we just saw, but let's change its name to `` . import React, { Component } from 'react'; import ChildComponent from './ChildComponent'; class ParentComponent extends Component { constructor() { super(); this.state = { ingredients: ['flour', 'eggs', 'milk', 'sugar', 'vanilla'], newIngredient: '' }; } handleIngredientInput = (event) => { this.setState({ newIngredient: event.target.value }); }; addIngredient = (event) => { event.preventDefault(); const ingredientsList = this.state.ingredients; ingredientsList.push(this.state.newIngredient); this.setState({ newIngredient: '', ingredients: ingredientsList }); }; render() { return ( <div> {this.state.ingredients.map((ingredient) => ( <ChildComponent thing={ingredient} /> ))} <form onSubmit={this.addIngredient}> <input type="text" onChange={this.handleIngredientInput} placeholder="Add a new ingredient" value={this.state.newIngredient} /> </form> </div> ); } } export default ParentComponent; The only two other differences in this component are that we're importing a ChildComponent and then using it inside our this.state.ingredients.map call. ChildComponent is another React component. Notice that we're using it just as if it were any other HTML tag. This is how we lay out our component hierarchy: the ChildComponent is rendered within the ParentComponent. We can see this to be the case if we open up the developer console and inspect these elements. child-left: parent-right Note also that we're passing each ingredient as a 'thing' to the ChildComponent component. This is how a parent component passes data to a child component. It doesn't need to be called 'thing'; you can call it whatever you want. Conceptually though, every piece of data that a parent component passes down to a child component is called a 'prop' in React lingo. Let's take a look now at the Child Component. It serves two purposes: to render the props data that it gets from a parent component, to add the ability for a user to click on it and have it toggle a strikethrough, indicating that the item is 'complete'. import React, { Component } from 'react'; class ChildComponent extends Component { constructor() { super(); this.state = { clicked: false }; } handleClick = () => { this.setState({ clicked: !this.state.clicked }); }; render() { const styles = this.state.clicked ? { textDecoration: 'line-through' } : { textDecoration: 'none' }; return ( <div style={styles} onClick={this.handleClick}> {this.props.thing} </div> ); } } export default ChildComponent; The overall structure of the child component is nothing we haven't seen. It's just another class component with its own s tate object and a method called handleClick . A component accesses its props via the this.props object. Any prop a parent component passes down to a child component is accessible inside the child component's this.prop object. So our child component keeps its own state that tracks whether the component has been clicked or not. Then at the top of the render function, it uses a ternary condition to determine whether the div tag that is being rendered should have a strikethrough or not. The handleClick method is then invoked via an onClick handler on the div tag; it does the work of toggling the this.state.clicked Boolean. The overall structure of React applications can be represented as a hierarchical tree structure, just like how the DOM itself is structure. There is an overarching root component at the top of the hierarchy that every other component sits underneath. Specifying that a component should be a child of some parent component is as simple as throwing it in the parent component's render function, just like how we did it in this example Core Concepts: 1. What is react? React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It uses components to update and render as your data changes. React manages the creation and continuous updating of DOM nodes in your Web page. It does not handle AJAX requests, Local Storage or style your website. IT is just a tool to dynamically render content on a webpage as a result of changes in 'state'. Because it's function is so limited in scope you may hear it referred to as a library… (not a framework … like Angular for example) and you may also hear it described as unopinionated. 2. Why use react? Works for teams and helps UI workflow patterns The components can be reusable Componentized UI is the future of web dev Declarative programming In the same way that you use HTML to declare what the user interface should look like, React provides the same mechanism in its `` method or the higher-level language known as JSX. React… like HTML is Declarative Declarative programming is often defined as any style of programming that is not imperative. A number of other common definitions attempt to define it by simply contrasting it with imperative programming. For example: A high-level program that describes what a computation should perform. Any programming language that lacks side effects A language with a clear correspondence to mathematical logic.[5] These definitions overlap substantially. D eclarative programming is a non-imperative style of programming in which programs describe their desired results without explicitly listing commands or steps that must be performed. Functional and logical programming languages are characterized by a declarative programming style. In a pure functional language, such as Haskell, all functions are without side effects, and state changes are only represented as functions that transform the state, which is explicitly represented as a first-class object in the program.— Wikipedia What is a React pure component? Based on the concept of purity in functional programming paradigms, a function is said to be pure if: Its return value is only determined by its input values Its return value is always the same for the same input values A React component is considered pure if it renders the same output for the same state and props. For class components like this, React provides the PureComponent base class. Class components that extend the React.PureComponent class are treated as pure components. Pure components have some performance improvements and render optimizations since React implements the shouldComponentUpdate() method for them with a shallow comparison for props and state. Are React functional components pure? Functional components are very useful in React, especially when you want to isolate state management from the component. That's why they are often called stateless components. However, functional components cannot leverage the performance improvements and render optimizations that come with React.PureComponent since they are not classes by definition. If you want React to treat a functional component as a pure component, you'll have to convert the functional component to a class component that extends React.PureComponent. function PercentageStat({ label, score = 0, total = Math.max(1, score) }) { return ( <div> <h6>{label}</h6> <span>{Math.round((score / total) * 100)}%</span> </div> ); } // CONVERTED TO PURE COMPONENT class PercentageStat extends React.PureComponent { render() { const { label, score = 0, total = Math.max(1, score) } = this.props; return ( <div> <h6>{label}</h6> <span>{Math.round((score / total) * 100)}%</span> </div> ); } } Reusability React encourages you to think in terms of reusability as you construct the user interface from elements and components that you create. When you make a list or a button, you can then reuse those components to show different data 'state' in the same UI structure as you have built for different data previously. Component-Based Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM. Learn Once, Write Anywhere We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using React Native. Speed Due to the use of a virtual DOM, React handles changes to a Web page more intelligently than just string manipulation. It is constantly monitors the virtual DOM for changes. It very efficiently reconciles changes in the virtual DOM with what it has already produced in the real DOM. This is what makes React one of the speediest front-end libraries available. 3. Who uses react? Companies such as Facebook app for android and Instagram Here is a link to a list of other companies who use react. Who uses react 4. Setting up react React can be set up in CodePen for quick practice development by adding react.js, react-dom and babel. It can also be set up by downloading a react starter project from GitHub installing node and following these instructions. Alternatively it can be set up through NPM like this. 5. Intro to eco system Composition, being able to wrap up sections of code into there own containers so they can be re used. How to make a large application? by combining small components to create a larger complex application. 6. Imperative vs Declarative (React is Declarative) Imperative, 'telling to computer HOW to do something' e.g looping over an array of numbers using a for loop. Declarative, is concerned about WHAT we want to happen. e.g using a reduce method on an array. Benefits of using declarative code: Reduce side effects Minimize mutability Less Bugs 7. Unidirectional Data Flow As the state collects from user interaction, the UI gets updated. Explicit Mutations Whenever the state needs to be updated in our application setState has to be called. this.setState({ highlight: !this.state.highlight, }) 7.1. First component Components are the building blocks of React. They are similar to a collection of HTML,CSS, JS and data specific to that component. They can be defined in pure JavaScript or JSX. Data is either received from a component's parent component, or it's contained in the component itself. Applications can be separated into smaller components like this… React components can be created using ES6 class like this. import React from 'react';class Hello extends React.Component { render () { return <h1>Hello, {this.props.name}!</h1>; } }export default Hello; At the top with have the code to bring react and react dom libraries in. React library is used for the react syntax. React DOM is used to update the DOM. We then have the Class section which creates the component. Render() describes the specific UI for the component. Return is used to return the JSX And Finally ReactDOM.render is used to update the DOM. 8. Data flow with props Small examples of data flow, see if you can get the code to work. https://codepen.io/bgoonz/embed/WNpoLbg?default-tab=&theme-id={% embed url=" https://codepen.io/bgoonz/embed/BaWQGQp?default-tab=\&theme-id=" %} 9. Creating lists with map {% embed url=" https://codepen.io/bgoonz/embed/XWMNoJr?default-tab=\&theme-id=" %} The parent component passes down to the child component as props. Using props to access names and map to loop through each list item. Then passing this by using props.{% embed url=" https://codepen.io/bgoonz/embed/gOmLZbX?default-tab=\&theme-id=" %} Checking data to see if Boolean is true then adding detail to the list.{% embed url=" https://codepen.io/bgoonz/embed/WNpoLbg?default-tab=\&theme-id=" %} 10. Prop types PropTypes allow you to declare the type (string, number, function, etc) of each prop being passed to a component. Then if a prop passed in isn't of the declared type you'll get a warning in the console. Excerpt from the React website: React — A JavaScript library for building user interfaces A JavaScript library for building user interfaces Declarative React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable and easier to debug. A Simple Component React components implement a render() method that takes input data and returns what to display. This example uses an XML-like syntax called JSX. Input data that is passed into the component can be accessed by render() via this.props. JSX is optional and not required to use React. Try the Babel REPL to see the raw JavaScript code produced by the JSX compilation step. In addition to taking input data (accessed via this.props), a component can maintain internal state data (accessed via this.state). When a component's state data changes, the rendered markup will be updated by re-invoking render(). An Application Using props and state, we can put together a small Todo application. This example uses state to track the current list of items as well as the text that the user has entered. Although event handlers appear to be rendered inline, they will be collected and implemented using event delegation. A Component Using External Plugins React allows you to interface with other libraries and frameworks. This example uses remarkable, an external Markdown library, to convert the <textarea>'s value in real time.
    https://bgoonz-blog.netlify.app/images/code.png
  • npx-create-react-app
    npx-create-react-app description: takes soooo much time! Generating React Project takes soooo much time! npx create-react-app my-app cd my-app npm start Babel can translate between different versions of javascript so that your code can run on browsers that are limited to ES5 compatibility... included by default with every new react project.|15:25:30|bryan@LAPTOP-9LGJ3JGS:[05-installing-nodejs] 05-installing-nodejs_exitstatus:0__________________________________________________________o> npx create-react-app my-app y-app npm start Creating a new React app in /mnt/c/MY-WEB-DEV/10-React-V3/05-installing-nodejs/my-app. Installing packages. This might take a couple of minutes. Installing react, react-dom, and react-scripts with cra-template... yarn add v1.22.5 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@1.2.13: The platform "linux" is incompatible with this module. info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation. info fsevents@2.3.2: The platform "linux" is incompatible with this module. info "fsevents@2.3.2" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.20.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta". [----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------[4/4] Building fresh packages... success Saved lockfile. success Saved 7 new dependencies. info Direct dependencies ├─ cra-template@1.1.2 ├─ react-dom@17.0.2 ├─ react-scripts@4.0.3 └─ react@17.0.2 info All dependencies ├─ cra-template@1.1.2 ├─ immer@8.0.1 ├─ react-dev-utils@11.0.4 ├─ react-dom@17.0.2 ├─ react-scripts@4.0.3 ├─ react@17.0.2 └─ scheduler@0.20.2 Done in 768.43s. Installing template dependencies using yarnpkg... yarn add v1.22.5 [1/4] Resolving packages... [2/4] Fetching packages... info fsevents@2.3.2: The platform "linux" is incompatible with this module. info "fsevents@2.3.2" is an optional dependency and failed compatibility check. Excluding it from installation. info fsevents@1.2.13: The platform "linux" is incompatible with this module. info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation. [3/4] Linking dependencies... warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.20.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta". warning " > @testing-library/user-event@12.8.3" has unmet peer dependency "@testing-library/dom@>=7.21.4". [4/4] Building fresh packages... success Saved lockfile. success Saved 17 new dependencies. info Direct dependencies ├─ @testing-library/jest-dom@5.11.10 ├─ @testing-library/react@11.2.5 ├─ @testing-library/user-event@12.8.3 ├─ react-dom@17.0.2 ├─ react@17.0.2 └─ web-vitals@1.1.1 info All dependencies ├─ @testing-library/dom@7.30.1 ├─ @testing-library/jest-dom@5.11.10 ├─ @testing-library/react@11.2.5 ├─ @testing-library/user-event@12.8.3 ├─ @types/aria-query@4.2.1 ├─ @types/jest@26.0.22 ├─ @types/testing-library__jest-dom@5.9.5 ├─ css.escape@1.5.1 ├─ css@3.0.0 ├─ dom-accessibility-api@0.5.4 ├─ lz-string@1.4.4 ├─ min-indent@1.0.1 ├─ react-dom@17.0.2 ├─ react@17.0.2 ├─ redent@3.0.0 ├─ strip-indent@3.0.0 └─ web-vitals@1.1.1 Done in 706.12s. Removing template package using yarnpkg... yarn remove v1.22.5 [1/2] Removing module cra-template... [2/2] Regenerating lockfile and installing missing dependencies... info fsevents@2.3.2: The platform "linux" is incompatible with this module. info "fsevents@2.3.2" is an optional dependency and failed compatibility check. Excluding it from installation. info fsevents@1.2.13: The platform "linux" is incompatible with this module. info "fsevents@1.2.13" is an optional dependency and failed compatibility check. Excluding it from installation. warning " > @testing-library/user-event@12.8.3" has unmet peer dependency "@testing-library/dom@>=7.21.4". warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.20.0" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta". success Uninstalled packages. Done in 619.62s. Success! Created my-app at /mnt/c/MY-WEB-DEV/10-React-V3/05-installing-nodejs/my-app Inside that directory, you can run several commands: yarn start Starts the development server. yarn build Bundles the app into static files for production. yarn test Starts the test runner. yarn eject Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can't go back! We suggest that you begin by typing: cd my-app yarn start Compiled successfully! You can now view my-app in the browser. Local: http://localhost:3000 On Your Network: http://172.25.168.12:3000 Note that the development build is not optimized. To create a production build, use yarn build.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    React Cheat Sheets: React Patterns: React Cheat Sheet React:<script src="https://unpkg.com/react@15/dist/react.js"></script>$ npm install react --save$ bower install react --save React DOM:<script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>$ npm install react-dom$ bower install react-dom --save Rendering Rendering (ES5) ReactDOM.render(React.createElement(Link, { name: 'HackHall.com' }), document.getElementById('menu')); Rendering (ES5+JSX) ReactDOM.render(<Link name="HackHall.com" />, document.getElementById('menu')); Server-side Rendering var ReactDOMServer = require('react-dom/server'); ReactDOMServer.renderToString(Link, { name: 'HackHall.com' }); ReactDOMServer.renderToStaticMarkup(Link, { name: 'HackHall.com' }); Components ES5 var Link = React.createClass({ displayName: 'Link', render: function () { return React.createElement('a', { className: 'btn', title: this.props.name }, 'Click ->', this.props.name); } }); ES5 + JSX var Link = React.createClass({ render: function () { return ( <a className="btn" title={this.props.name}> Click -> this.props.name </a> ); } }); ES6 + JSX class Link extends React.Component { render() { return ( <a className="btn" title={this.props.name}> Click -> this.props.name </a> ); } } npm install --save react // declarative and flexible JavaScript library for building UI npm install --save react-dom // serves as the entry point of the DOM-related rendering paths npm install --save prop-types // runtime type checking for React props and similar objects // notes: don't forget the command lines/* ******************************************************************************************* * REACT * https://reactjs.org/docs/react-api.html * ******************************************************************************************* */ // Create and return a new React element of the given type. // Code written with JSX will be converted to use React.createElement(). // You will not typically invoke React.createElement() directly if you are using JSX. React.createElement( type, [props], [...children] ) // Clone and return a new React element using element as the starting point. // The resulting element will have the original element's props with the new props merged in shallowly. React.cloneElement( element, [props], [...children] ) // Verifies the object is a React element. Returns true or false. React.isValidElement(object) React.Children // provides utilities for dealing with the this.props.children opaque data structure. // Invokes a function on every immediate child contained within children with this set to thisArg. React.Children.map(children, function[(thisArg)]) // Like React.Children.map() but does not return an array. React.Children.forEach(children, function[(thisArg)]) // Returns the total number of components in children, // equal to the number of times that a callback passed to map or forEach would be invoked. React.Children.count(children) // Verifies that children has only one child (a React element) and returns it. // Otherwise this method throws an error. React.Children.only(children) // Returns the children opaque data structure as a flat array with keys assigned to each child. // Useful if you want to manipulate collections of children in your render methods, // especially if you want to reorder or slice this.props.children before passing it down. React.Children.toArray(children) // The React.Fragment component lets you return multiple elements in a render() method without creating an additional DOM element // You can also use it with the shorthand <></> syntax. React.Fragment /* ******************************************************************************************* * REACT.COMPONENT * React.Component is an abstract base class, so it rarely makes sense to refer to React.Component * directly. Instead, you will typically subclass it, and define at least a render() method. * https://reactjs.org/docs/react-component.html * ******************************************************************************************* */ class Component extends React.Component { // Will be called before it is mounted constructor(props) { // Call this method before any other statement // or this.props will be undefined in the constructor super(props); // The constructor is also often used to bind event handlers to the class instance. // Binding makes sure the method has access to component attributes like this.props and this.state this.method = this.method.bind(this); // The constructor is the right place to initialize state. this.state = { active: true, // In rare cases, it's okay to initialize state based on props. // This effectively “forks” the props and sets the state with the initial props. // If you “fork” props by using them for state, you might also want to implement componentWillReceiveProps(nextProps) // to keep the state up-to-date with them. But lifting state up is often easier and less bug-prone. color: props.initialColor }; } // Enqueues changes to the component state and // tells React that this component and its children need to be re-rendered with the updated state. // setState() does not always immediately update the component. It may batch or defer the update until later. // This makes reading this.state right after calling setState() a potential pitfall. // Instead, use componentDidUpdate or a setState callback. // You may optionally pass an object as the first argument to setState() instead of a function. setState(updater[, callback]) { } // Invoked just before mounting occurs (before render()) // This is the only lifecycle hook called on server rendering. componentWillMount() { } // Invoked immediately after a component is mounted. // Initialization that requires DOM nodes should go here. // If you need to load data from a remote endpoint, this is a good place to instantiate the network request. // This method is a good place to set up any subscriptions. If you do that, don't forget to unsubscribe in componentWillUnmount(). componentDidMount() { } // Invoked before a mounted component receives new props. // If you need to update the state in response to prop changes (for example, to reset it), // you may compare this.props and nextProps and perform state transitions using this.setState() in this method. componentWillReceiveProps(nextProps) { } // Let React know if a component's output is not affected by the current change in state or props. // The default behavior is to re-render on every state change, and in the vast majority of cases you should rely on the default behavior. // shouldComponentUpdate() is invoked before rendering when new props or state are being received. Defaults to true. // This method is not called for the initial render or when forceUpdate() is used. // Returning false does not prevent child components from re-rendering when their state changes. shouldComponentUpdate(nextProps, nextState) { } // Invoked just before rendering when new props or state are being received. // Use this as an opportunity to perform preparation before an update occurs. This method is not called for the initial render. // Note that you cannot call this.setState() here; nor should you do anything else // (e.g. dispatch a Redux action) that would trigger an update to a React component before componentWillUpdate() returns. // If you need to update state in response to props changes, use componentWillReceiveProps() instead. componentWillUpdate(nextProps, nextState) { } // Invoked immediately after updating occurs. This method is not called for the initial render. // Use this as an opportunity to operate on the DOM when the component has been updated. // This is also a good place to do network requests as long as you compare the current props to previous props (e.g. a network request may not be necessary if the props have not changed). componentDidUpdate(prevProps, prevState) { } // Invoked immediately before a component is unmounted and destroyed. // Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, // or cleaning up any subscriptions that were created in componentDidMount(). componentWillUnmount() { } // Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, // log those errors, and display a fallback UI instead of the component tree that crashed. // Error boundaries catch errors during rendering, in lifecycle methods, and in constructors of the whole tree below them. componentDidCatch() { } // This method is required. // It should be pure, meaning that it does not modify component state, // it returns the same result each time it's invoked, and // it does not directly interact with the browser (use lifecycle methods for this) // It must return one of the following types: react elements, string and numbers, portals, null or booleans. render() { // Contains the props that were defined by the caller of this component. console.log(this.props); // Contains data specific to this component that may change over time. // The state is user-defined, and it should be a plain JavaScript object. // If you don't use it in render(), it shouldn't be in the state. // For example, you can put timer IDs directly on the instance. // Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. // Treat this.state as if it were immutable. console.log(this.state); return ( <div> {/* Comment goes here */} Hello, {this.props.name}! </div> ); } } // Can be defined as a property on the component class itself, to set the default props for the class. // This is used for undefined props, but not for null props. Component.defaultProps = { color: 'blue' }; component = new Component(); // By default, when your component's state or props change, your component will re-render. // If your render() method depends on some other data, you can tell React that the component needs re-rendering by calling forceUpdate(). // Normally you should try to avoid all uses of forceUpdate() and only read from this.props and this.state in render(). component.forceUpdate(callback) /* ******************************************************************************************* * REACT.DOM * The react-dom package provides DOM-specific methods that can be used at the top level of * your app and as an escape hatch to get outside of the React model if you need to. * Most of your components should not need to use this module. * https://reactjs.org/docs/react-dom.html * ******************************************************************************************* */ // Render a React element into the DOM in the supplied container and return a reference // to the component (or returns null for stateless components). ReactDOM.render(element, container[, callback]) // Same as render(), but is used to hydrate a container whose HTML contents were rendered // by ReactDOMServer. React will attempt to attach event listeners to the existing markup. ReactDOM.hydrate(element, container[, callback]) // Remove a mounted React component from the DOM and clean up its event handlers and state. // If no component was mounted in the container, calling this function does nothing. // Returns true if a component was unmounted and false if there was no component to unmount. ReactDOM.unmountComponentAtNode(container) // If this component has been mounted into the DOM, this returns the corresponding native browser // DOM element. This method is useful for reading values out of the DOM, such as form field values // and performing DOM measurements. In most cases, you can attach a ref to the DOM node and avoid // using findDOMNode at all. ReactDOM.findDOMNode(component) // Creates a portal. Portals provide a way to render children into a DOM node that exists outside // the hierarchy of the DOM component. ReactDOM.createPortal(child, container) /* ******************************************************************************************* * REACTDOMSERVER * The ReactDOMServer object enables you to render components to static markup. * https://reactjs.org/docs/react-dom.html * ******************************************************************************************* */ // Render a React element to its initial HTML. React will return an HTML string. // You can use this method to generate HTML on the server and send the markup down on the initial // request for faster page loads and to allow search engines to crawl your pages for SEO purposes. ReactDOMServer.renderToString(element) // Similar to renderToString, except this doesn't create extra DOM attributes that React uses // internally, such as data-reactroot. This is useful if you want to use React as a simple static // page generator, as stripping away the extra attributes can save some bytes. ReactDOMServer.renderToStaticMarkup(element) // Render a React element to its initial HTML. Returns a Readable stream that outputs an HTML string. // The HTML output by this stream is exactly equal to what ReactDOMServer.renderToString would return. // You can use this method to generate HTML on the server and send the markup down on the initial // request for faster page loads and to allow search engines to crawl your pages for SEO purposes. ReactDOMServer.renderToNodeStream(element) // Similar to renderToNodeStream, except this doesn't create extra DOM attributes that React uses // internally, such as data-reactroot. This is useful if you want to use React as a simple static // page generator, as stripping away the extra attributes can save some bytes. ReactDOMServer.renderToStaticNodeStream(element) /* ******************************************************************************************* * TYPECHECKING WITH PROPTYPES * https://reactjs.org/docs/typechecking-with-proptypes.html * ******************************************************************************************* */ import PropTypes from 'prop-types'; MyComponent.propTypes = { // You can declare that a prop is a specific JS type. By default, these // are all optional. optionalArray: PropTypes.array, optionalBool: PropTypes.bool, optionalFunc: PropTypes.func, optionalNumber: PropTypes.number, optionalObject: PropTypes.object, optionalString: PropTypes.string, optionalSymbol: PropTypes.symbol, // Anything that can be rendered: numbers, strings, elements or an array // (or fragment) containing these types. optionalNode: PropTypes.node, // A React element. optionalElement: PropTypes.element, // You can also declare that a prop is an instance of a class. This uses // JS's instanceof operator. optionalMessage: PropTypes.instanceOf(Message), // You can ensure that your prop is limited to specific values by treating // it as an enum. optionalEnum: PropTypes.oneOf(['News', 'Photos']), // An object that could be one of many types optionalUnion: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.instanceOf(Message) ]), // An array of a certain type optionalArrayOf: PropTypes.arrayOf(PropTypes.number), // An object with property values of a certain type optionalObjectOf: PropTypes.objectOf(PropTypes.number), // An object taking on a particular shape optionalObjectWithShape: PropTypes.shape({ color: PropTypes.string, fontSize: PropTypes.number }), // You can chain any of the above with `isRequired` to make sure a warning // is shown if the prop isn't provided. requiredFunc: PropTypes.func.isRequired, // A value of any data type requiredAny: PropTypes.any.isRequired, // You can also specify a custom validator. It should return an Error // object if the validation fails. Don't `console.warn` or throw, as this // won't work inside `oneOfType`. customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error( 'Invalid prop `' + propName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } }, // You can also supply a custom validator to `arrayOf` and `objectOf`. // It should return an Error object if the validation fails. The validator // will be called for each key in the array or object. The first two // arguments of the validator are the array or object itself, and the // current item's key. customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) { if (!/matchme/.test(propValue[key])) { return new Error( 'Invalid prop `' + propFullName + '` supplied to' + ' `' + componentName + '`. Validation failed.' ); } }) }; Advanced Components Options (ES5) propTypes object: Type validation in development mode getDefaultProps function(): object of default props getInitialState function(): object of the initial state ES5: var Link = React.createClass({ propTypes: { name: React.PropTypes.string }, getDefaultProps: function () { return { initialCount: 0 }; }, getInitialState: function () { return { count: this.props.initialCount }; }, tick: function () { this.setState({ count: this.state.count + 1 }); }, render: function () { return React.createElement( 'a', { className: 'btn', href: '#', title: this.props.name, onClick: this.tick.bind(this) }, 'Click ->', this.props.name ? this.props.name : 'webapplog.com', ' (Clicked: ' + this.state.count + ')' ); } }); ES5 + JSX: var Link = React.createClass({ propTypes: { name: React.PropTypes.string }, getDefaultProps: function () { return { initialCount: 0 }; }, getInitialState: function () { return { count: this.props.initialCount }; }, tick: function () { this.setState({ count: this.state.count + 1 }); }, render: function () { return ( <a onClick={this.tick.bind(this)} href="#" className="btn" title={this.props.name}> Click -> {this.props.name ? this.props.name : 'webapplog.com'} (Clicked: {this.state.count}) </a> ); } }); ES6 + JSX: export class Link extends React.Component { constructor(props) { super(props); this.state = { count: props.initialCount }; } tick() { this.setState({ count: this.state.count + 1 }); } render() { return ( <a onClick={this.tick.bind(this)} href="#" className="btn" title={this.props.name}> Click -> {this.props.name ? this.props.name : 'webapplog.com'} (Clicked: {this.state.count}) </a> ); } } Link.propTypes = { initialCount: React.PropTypes.number }; Link.defaultProps = { initialCount: 0 }; Lifecycle Events Modern React lifecycle methods (v16+) Legacy Lifecycle Events: componentWillMount function() componentDidMount function() componentWillReceiveProps function(nextProps) shouldComponentUpdate function(nextProps, nextState)-> bool componentWillUpdate function(nextProps, nextState) componentDidUpdate function(prevProps, prevState) componentWillUnmount function() Sequence of lifecycle events: Inspired by http://react.tips Special Props key: Unique identifier for an element to turn arrays/lists into hashes for better performance, e.g., key={id} ref: Reference to an element via this.refs.NAME, e.g., ref="email" will create this.refs.email DOM node or ReactDOM.findDOMNode(this.refs.email) style: Accept an object of styles, instead of a string (immutable since v0.14), e.g., style={{color: red}} className: the HTML class attribute, e.g., className="btn" htmlFor: the HTML for attribute, e.g., htmlFor="email" dangerouslySetInnerHTML: raw HTML by providing an object with the key __html children: content of the element via this.props.children, e.g., this.props.children[0] data-NAME: custom attribute, e.g., data-tooltip-text="..." propTypes Types available under React.PropTypes: any array bool element func node number object string To make required, append .isRequired. More methods: instanceOf(constructor) oneOf(['News', 'Photos']) oneOfType([propType, propType]) Custom Validation propTypes: { customProp: function(props, propName, componentName) { if (!/regExPattern/.test(props[propName])) { return new Error('Validation failed!'); } } } Component Properties and Methods Properties: this.refs: Lists components with a ref prop this.props: Any props passed to an element (immutable) this.state: State set by setState and getInitialState (muttable) — avoid setting state manually with this.state=... this.isMounted: Flag whether the element has a corresponding DOM node or not Methods: setState(changes): Change state (partially) to this.state and trigger re-render replaceState(newState): Replace this.state and trigger re-render forceUpdate(): Trigger DOM re-render immediately React Addons As npm modules: react-addons-css-transition-group react-addons-perf react-addons-test-utils react-addons-pure-render-mixin react-addons-linked-state-mixin react-addons-clone-with-props react-addons-create-fragment react-addons-css-transition-group react-addons-linked-state-mixin react-addons-pure-render-mixin react-addons-shallow-compare react-addons-transition-group react-addons-update React Components https://github.com/brillout/awesome-react-components and http://devarchy.com/react-components: List of React components Material-UI: Material design React components http://react-toolbox.com: Set of React components that implement Google Material Design specification https://js.coach: Opinionated catalog of open source JS (mostly React) packages https://react.rocks: Catalog of React components https://khan.github.io/react-components: Khan Academy React components http://www.reactjsx.com: Registry of React components
    https://bgoonz-blog.netlify.app/images/code.png
  • Bash-Commands
    Bash-Commands My Commands: Find: To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG): find . -iname "*.jpg" To find directories: find . -type d To find files: find . -type f To find files by octal permission: find . -type f -perm 777 To find files with setuid bit set: find . -xdev ( -perm -4000 ) -type f -print0 | xargs -0 ls -l To find files with extension '.txt' and remove them: find ./path/ -name '*.txt' -exec rm '{}' ; To find files with extension '.txt' and look for a string into them: find ./path/ -name '*.txt' | xargs grep 'string' To find files with size bigger than 5 Mebibyte and sort them by size: find . -size +5M -type f -print0 | xargs -0 ls -Ssh | sort -z To find files bigger than 2 Megabyte and list them: find . -type f -size +200000000c -exec ls -lh {} ; | awk '{ print $9 ": " $5 }' To find files modified more than 7 days ago and list file information: find . -type f -mtime +7d -ls To find symlinks owned by a user and list file information: find . -type l -user -ls To search for and delete empty directories: find . -type d -empty -exec rmdir {} ; To search for directories named build at a max depth of 2 directories: find . -maxdepth 2 -name build -type d To search all files who are not in .git directory: find . ! -iwholename '.git' -type f To find all files that have the same node (hard link) as MY FILE HERE: find . -type f -samefile MY FILE HERE 2>/dev/null To find all files in the current directory and modify their permissions: find . -type f -exec chmod 644 {} ; 1. Remove spaces from file and folder names and then remove numbers from files and folder names.... Description: need to : sudo apt install rename Notes: Issue when renaming file without numbers collides with existing file name... code: find . -name "* *" -type d | rename 's/ /_/g' find . -name "* *" -type f | rename 's/ /_/g' ```sh find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh for i in *.html; do mv "$i" "${i%-*}.html"; done for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done --- ### Description: combine the contents of every file in the contaning directory. >Notes: this includes the contents of the file it's self... ###### code: ```js //APPEND-DIR.js const fs = require('fs'); let cat = require('child_process') .execSync('cat *') .toString('UTF-8'); fs.writeFile('output.md', cat, err => { if (err) throw err; }); 2. Download Website Using Wget: Description: Notes: ==> sudo apt install wget code: wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/ 3. Clean Out Messy Git Repo: Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders Notes: To clear up clutter in repositories that only get used on your local machine. code: find . -empty -type d -print -delete find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + 4. clone all of a user's git repositories Description: clone all of a user or organization's git repositories. Notes: code: Generalized: CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone Clone all Git User CNTX={users}; NAME={bgoonz}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone Clone all Git Organization: CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone 5. Git Workflow Description: code: git pull git init git add . git commit -m"update" git push -u origin master git init git add . git commit -m"update" git push -u origin main git init git add . git commit -m"update" git push -u origin bryan-guner git init git add . git commit -m"update" git push -u origin gh-pages git init git add . git commit -m"update" git push -u origin preview 6. Recursive Unzip In Place Description: recursively unzips folders and then deletes the zip file by the same name. Notes: code: find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; find . -name "*.zip" -type f -print -delete 7. git pull keeping local changes: Description: Notes: code: git stash git pull git stash pop 8. Prettier Code Formatter: Description: Notes: code: sudo npm i prettier -g prettier --write . 9. Pandoc Description: Notes: code: find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \; find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \; 10. Gitpod Installs Description: Notes: code: sudo apt install tree sudo apt install pandoc -y sudo apt install rename -y sudo apt install black -y sudo apt install wget -y npm i lebab -g npm i prettier -g npm i npm-recursive-install -g black . prettier --write . npm-recursive-install 11. Repo Utils Package: Description: my standard repo utis package Notes: code: npm i @bgoonz11/repoutils 12. Unix Tree Package Usage: Description: Notes: code: tree -d -I 'node_modules' tree -I 'node_modules' tree -f -I 'node_modules' >TREE.md tree -f -L 2 >README.md tree -f -I 'node_modules' >listing-path.md tree -f -I 'node_modules' -d >TREE.md tree -f >README.md 13. Find & Replace string in file & folder names recursively.. Description: Notes: code: find . -type f -exec rename 's/string1/string2/g' {} + find . -type d -exec rename 's/-master//g' {} + find . -type f -exec rename 's/\.download//g' {} + find . -type d -exec rename 's/-main//g' {} + rename 's/\.js\.download$/.js/' *.js\.download rename 's/\.html\.markdown$/.md/' *.html\.markdown find . -type d -exec rename 's/es6//g' {} + 14. Remove double extensions : Description: Notes: code:#!/bin/bash for file in *.md.md do mv "${file}" "${file%.md}" done #!/bin/bash for file in *.html.html do mv "${file}" "${file%.html}" done #!/bin/bash for file in *.html.png do mv "${file}" "${file%.png}" done for file in *.jpg.jpg do mv "${file}" "${file%.png}" done 15. Truncate folder names down to 12 characters: Description: Notes: code: for d in ./*; do mv $d ${d:0:12}; done 16.Appendir.js Description: combine the contents of every file in the contaning directory. Notes: this includes the contents of the file it's self... code://APPEND-DIR.js const fs = require('fs'); let cat = require('child_process') .execSync('cat *') .toString('UTF-8'); fs.writeFile('output.md', cat, err => { if (err) throw err; }); 17. Replace space in filename with underscore Description: followed by replace '#' with '_' in directory name Notes: Can be re-purposed to find and replace any set of strings in file or folder names. code: find . -name "* *" -type f | rename 's/_//g' find . -name "* *" -type d | rename 's/#/_/g' 18. Filter & delete files by name and extension Description: Notes: code: find . -name '.bin' -type d -prune -exec rm -rf '{}' + find . -name '*.html' -type d -prune -exec rm -rf '{}' + find . -name 'nav-index' -type d -prune -exec rm -rf '{}' + find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' + find . -name 'right.html' -type f -prune -exec rm -rf '{}' + find . -name 'left.html' -type f -prune -exec rm -rf '{}' + 19. Remove lines containing string: Description: Notes: Remove lines not containing '.js' sudo sed -i '/\.js/!d' ./*scrap2.md code: sudo sed -i '/githubusercontent/d' ./*sandbox.md sudo sed -i '/githubusercontent/d' ./*scrap2.md sudo sed -i '/github\.com/d' ./*out.md sudo sed -i '/author/d' ./* 20. Remove duplicate lines from a text file Description: Notes: //...syntax of uniq...// $uniq [OPTION] [INPUT[OUTPUT]] The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn’t specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn’t specified then uniq writes to the standard output. Now, let’s understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq. code: sudo apt install uniq uniq -u input.txt output.txt 21. Remove lines containing string: Description: Notes: code: sudo sed -i '/githubusercontent/d' ./*sandbox.md sudo sed -i '/githubusercontent/d' ./*scrap2.md sudo sed -i '/github\.com/d' ./*out.md --- title: add_days tags: date,intermediate firstSeen: 2020-10-28T16:19:04+02:00 lastUpdated: 2020-10-28T16:19:04+02:00 --- sudo sed -i '/title:/d' ./*output.md sudo sed -i '/firstSeen/d' ./*output.md sudo sed -i '/lastUpdated/d' ./*output.md sudo sed -i '/tags:/d' ./*output.md sudo sed -i '/badstring/d' ./* sudo sed -i '/stargazers/d' ./repo.txt sudo sed -i '/node_modules/d' ./index.html sudo sed -i '/right\.html/d' ./index.html sudo sed -i '/right\.html/d' ./right.html 22. Zip directory excluding .git and node_modules all the way down (Linux) Description: Notes: code:#!/bin/bash TSTAMP=`date '+%Y%m%d-%H%M%S'` zip -r $1.$TSTAMP.zip $1 -x "**.git/*" -x "**node_modules/*" `shift; echo $@;` printf "\nCreated: $1.$TSTAMP.zip\n" # usage: # - zipdir thedir # - zip thedir -x "**anotherexcludedsubdir/*" (important the double quotes to prevent glob expansion) # if in windows/git-bash, add 'zip' command this way: # https://stackoverflow.com/a/55749636/1482990 23. Delete files containing a certain string: Description: Notes: code: find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh vi doit.sh // check for murphy and his law source doit.sh 24. Description: Notes: code:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="sitemap.html" out="basename $out.html" html="sitemap.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/bgoonz/GIT-CDN-FILES/mdn-article.css">' echo '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/bgoonz/GIT-CDN-FILES/markdown-to-html-style.css">' echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<li><a href=\""$1"\">",$1,"&nbsp;</a></li>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html 25. Index of Iframes Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags. Notes: Useful Follow up Code: code:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="index.html" out="basename $out.html" html="index.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<iframe src=\""$1"\">","</iframe>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html 26. Filter Corrupted Git Repo For Troublesome File: Description: Notes: code: git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD 27. OVERWRITE LOCAL CHANGES: Description: Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected. Notes: First, run a fetch to update all origin/ refs to latest: code: git fetch --all # Backup your current branch: git branch backup-master # Then, you have two options: git reset --hard origin/master # OR If you are on some other branch: git reset --hard origin/<branch_name> # Explanation: # git fetch downloads the latest from remote without trying to merge or rebase anything. # Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master git fetch --all git reset --hard origin/master 28. Remove Submodules: Description: To remove a submodule you need to: Notes: Delete the relevant section from the .gitmodules file. Stage the .gitmodules changes git add .gitmodules Delete the relevant section from .git/config. Run git rm --cached path to submodule (no trailing slash). Run rm -rf .git/modules/path to submodule (no trailing slash). Commit git commit -m "Removed submodule " Delete the now untracked submodule files rm -rf path to submodule code: git submodule deinit 29. GET GISTS Description: Notes: code: sudo apt install wget wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget 30. Remove Remote OriginL Description: Notes: code: git remote remove origin 31. just clone .git folder: Description: Notes: code: git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git 32. Undo recent pull request: Description: Notes: code: git reset --hard master@{"10 minutes ago"} 33. Lebab Description: ES5 --> ES6 Notes: code:# Safe: lebab --replace ./ --transform arrow lebab --replace ./ --transform arrow-return lebab --replace ./ --transform for-of lebab --replace ./ --transform for-each lebab --replace ./ --transform arg-rest lebab --replace ./ --transform arg-spread lebab --replace ./ --transform obj-method lebab --replace ./ --transform obj-shorthand lebab --replace ./ --transform multi-var # ALL: lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow lebab --replace ./ --transform let lebab --replace ./ --transform arg-spread lebab --replace ./ --transform arg-rest lebab --replace ./ --transform for-each lebab --replace ./ --transform for-of lebab --replace ./ --transform commonjs lebab --replace ./ --transform exponent lebab --replace ./ --transform multi-var lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param lebab --replace ./ --transform includes lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow lebab --replace ./ --transform arg-spread lebab --replace ./ --transform arg-rest lebab --replace ./ --transform for-each lebab --replace ./ --transform for-of lebab --replace ./ --transform commonjs lebab --replace ./ --transform exponent lebab --replace ./ --transform multi-var lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param lebab --replace ./ --transform includes 34. Troubleshoot Ubuntu Input/Output Error Description: Open Powershell as Administrator... Notes: code: wsl.exe --shutdown Get-Service LxssManager | Restart-Service 35. Export Medium as Markdown Description: Notes: code: npm i mediumexporter -g mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md 36. Delete files in violation of a given size range (100MB for git) Description: Notes: code: find . -size +75M -a -print -a -exec rm -f {} \; find . -size +98M -a -print -a -exec rm -f {} \; 37. download all links of given file type Description: Notes: code: wget -r -A.pdf https://overapi.com/git 38. Kill all node processes Description: Notes: code: killall -s KILL node 39. Remove string from file names recursively Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories. code: find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} + find . -type f -exec rename 's/-master//g' {} + Notes: The same could be done for folder names by changing the -type f flag (for file) to a -type d flag (for directory) find <mydir> -type d -exec sed -i 's/<string1>/<string2>/g' {} + find . -type d -exec rename 's/-master//g' {} + 40. Remove spaces from file and folder names recursively Description: replaces spaces in file and folder names with an _ underscore Notes: need to run sudo apt install rename to use this command code: find . -name "* *" -type d | rename 's/ /_/g' find . -name "* *" -type f | rename 's/ /_/g' 41. Zip Each subdirectories in a given directory into their own zip file Description: Notes: code: for i in */; do zip -r "${i%/}.zip" "$i"; done 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. Unzip PowerShell Description: Notes: code: PARAM ( [string] $ZipFilesPath = "./", [string] $UnzipPath = "./RESULT" ) $Shell = New-Object -com Shell.Application $Location = $Shell.NameSpace($UnzipPath) $ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP $progress = 1 foreach ($ZipFile in $ZipFiles) { Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" $ZipFolder = $Shell.NameSpace($ZipFile.fullname) $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - http://msdn.microsoft.com/en-us/library/bb787866%28VS.85%29.aspx $progress++ } 92. return to bash from zsh Description: Notes: code: sudo apt --purge remove zsh 93. Symbolic Link Description: to working directory Notes: code: ln -s "$(pwd)" ~/NameOfLink ln -s "$(pwd)" ~/Downloads 94. auto generate readme Description: rename existing readme to blueprint.md Notes: code: npx @appnest/readme generate 95. Log into postgres: Description: Notes: code: sudo -u postgres psql 96. URL To Subscribe To YouTube Channel Description: Notes: code: https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1 97. Embed Repl.it In Medium Post: code: https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/node-db1-project?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/interview-prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/Database-Prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com 98. Description: Notes: code: find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + 99. Cheat Sheet Description: Notes: code:#!/bin/bash ############################################################################## # SHORTCUTS and HISTORY ############################################################################## CTRL+A # move to beginning of line CTRL+B # moves backward one character CTRL+C # halts the current command CTRL+D # deletes one character backward or logs out of current session, similar to exit CTRL+E # moves to end of line CTRL+F # moves forward one character CTRL+G # aborts the current editing command and ring the terminal bell CTRL+H # deletes one character under cursor (same as DELETE) CTRL+J # same as RETURN CTRL+K # deletes (kill) forward to end of line CTRL+L # clears screen and redisplay the line CTRL+M # same as RETURN CTRL+N # next line in command history CTRL+O # same as RETURN, then displays next line in history file CTRL+P # previous line in command history CTRL+Q # resumes suspended shell output CTRL+R # searches backward CTRL+S # searches forward or suspends shell output CTRL+T # transposes two characters CTRL+U # kills backward from point to the beginning of line CTRL+V # makes the next character typed verbatim CTRL+W # kills the word behind the cursor CTRL+X # lists the possible filename completions of the current word CTRL+Y # retrieves (yank) last item killed CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background ALT+B # moves backward one word ALT+D # deletes next word ALT+F # moves forward one word ALT+H # deletes one character backward ALT+T # transposes two words ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. ALT+U # capitalizes every character from the current cursor position to the end of the word ALT+L # uncapitalizes every character from the current cursor position to the end of the word ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. ALT+R # reverts any changes to a command you’ve pulled from your history if you’ve edited it. ALT+? # list possible completions to what is typed ALT+^ # expand line to most recent match from history CTRL+X then ( # start recording a keyboard macro CTRL+X then ) # finish recording keyboard macro CTRL+X then E # recall last recorded keyboard macro CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands BACKSPACE # deletes one character backward DELETE # deletes one character under cursor history # shows command line history !! # repeats the last command !<n> # refers to command line 'n' !<string> # refers to command starting with 'string' exit # logs out of current session ############################################################################## # BASH BASICS ############################################################################## env # displays all environment variables echo $SHELL # displays the shell you're using echo $BASH_VERSION # displays bash version bash # if you want to use bash (type exit to go back to your previously opened shell) whereis bash # locates the binary, source and manual-page for a command which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) clear # clears content on window (hide displayed lines) ############################################################################## # FILE COMMANDS ############################################################################## ls # lists your files in current directory, ls <dir> to print files in a specific directory ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified ls -a # lists all files in 'long format', including hidden files (name beginning with '.') ln -s <filename> <link> # creates symbolic link to file readlink <filename> # shows where a symbolic links points to tree # show directories and subdirectories in easilly readable file tree mc # terminal file explorer (alternative to ncdu) touch <filename> # creates or updates (edit) your file mktemp -t <filename> # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) cat <filename> # prints file raw content (will not be interpreted) any_command > <filename> # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) more <filename> # shows the first part of a file (move with space and type q to quit) head <filename> # outputs the first lines of file (default: 10 lines) tail <filename> # outputs the last lines of file (useful with -f option) (default: 10 lines) vim <filename> # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist mv <filename1> <dest> # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) cp <filename1> <dest> # copies a file rm <filename> # removes a file find . -name <name> <type> # searches for a file or a directory in the current directory and all its sub-directories by its name diff <filename1> <filename2> # compares files, and shows where they differ wc <filename> # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations sort <filename> # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. sort -t -k <filename> # sorts the contents on specific sort key field starting from 1, using the field separator t. rev # reverse string characters (hello becomes olleh) chmod -options <filename> # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) gzip <filename> # compresses files using gzip algorithm gunzip <filename> # uncompresses files compressed by gzip gzcat <filename> # lets you look at gzipped file without actually having to gunzip it lpr <filename> # prints the file lpq # checks out the printer queue lprm <jobnumber> # removes something from the printer queue genscript # converts plain text files into postscript for printing and gives you some options for formatting dvips <filename> # prints .dvi files (i.e. files produced by LaTeX) grep <pattern> <filenames> # looks for the string in the files grep -r <pattern> <dir> # search recursively for pattern in directory head -n file_name | tail +n # Print nth line from file. head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines. ############################################################################## # DIRECTORY COMMANDS ############################################################################## mkdir <dirname> # makes a new directory rmdir <dirname> # remove an empty directory rmdir -rf <dirname> # remove a non-empty directory mv <dir1> <dir2> # rename a directory from <dir1> to <dir2> cd # changes to home cd .. # changes to the parent directory cd <dirname> # changes directory cp -r <dir1> <dir2> # copy <dir1> into <dir2> including sub-directories pwd # tells you where you currently are cd ~ # changes to home. cd - # changes to previous working directory ############################################################################## # SSH, SYSTEM INFO & NETWORK COMMANDS ############################################################################## ssh user@host # connects to host as user ssh -p <port> user@host # connects to host on specified port as user ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login whoami # returns your username passwd # lets you change your password quota -v # shows what your disk quota is date # shows the current date and time cal # shows the month's calendar uptime # shows current uptime w # displays whois online finger <user> # displays information about user uname -a # shows kernel information man <command> # shows the manual for specified command df # shows disk usage du <filename> # shows the disk usage of the files and directories in filename (du -s give only a total) last <yourUsername> # lists your last logins ps -u yourusername # lists your processes kill <PID> # kills the processes with the ID you gave killall <processname> # kill all processes with the name top # displays your currently active processes lsof # lists open files bg # lists stopped or background jobs ; resume a stopped job in the background fg # brings the most recent job in the foreground fg <job> # brings job to the foreground ping <host> # pings host and outputs results whois <domain> # gets whois information for domain dig <domain> # gets DNS information for domain dig -x <host> # reverses lookup host wget <file> # downloads file time <command> # report time consumed by command execution ############################################################################## # VARIABLES ############################################################################## varname=value # defines a variable varname=value command # defines a variable to be in the environment of a particular subprocess echo $varname # checks a variable's value echo $$ # prints process ID of the current shell echo $! # prints process ID of the most recently invoked background job echo $? # displays the exit status of the last command read <varname> # reads a string from the input and assigns it to a variable read -p "prompt" <varname> # same as above but outputs a prompt to ask user for value column -t <filename> # display info in pretty columns (often used with pipe) let <varname> = <equation> # performs mathematical calculation using operators like +, -, *, /, % export VARNAME=value # defines an environment variable (will be available in subprocesses) array[0]=valA # how to define an array array[1]=valB array[2]=valC array=([2]=valC [0]=valA [1]=valB) # another way array=(valA valB valC) # and another ${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed ${#array[i]} # to find out the length of any element in the array ${#array[@]} # to find out how many values there are in the array declare -a # the variables are treated as arrays declare -f # uses function names only declare -F # displays function names without definitions declare -i # the variables are treated as integers declare -r # makes the variables read-only declare -x # marks the variables for export via the environment ${varname:-word} # if varname exists and isn't null, return its value; otherwise return word ${varname:word} # if varname exists and isn't null, return its value; otherwise return word ${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value ${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script ${varname:+word} # if varname exists and isn't null, return word; otherwise return null ${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters ${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest ${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest ${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest ${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest ${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced ${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced ${#varname} # returns the length of the value of the variable as a character string *(patternlist) # matches zero or more occurrences of the given patterns +(patternlist) # matches one or more occurrences of the given patterns ?(patternlist) # matches zero or one occurrence of the given patterns @(patternlist) # matches exactly one of the given patterns !(patternlist) # matches anything except one of the given patterns $(UNIX command) # command substitution: runs the command and returns standard output ############################################################################## # FUNCTIONS ############################################################################## # The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth. # $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters. function functname() { shell commands } unset -f functname # deletes a function definition declare -f # displays all defined functions in your login session ############################################################################## # FLOW CONTROLS ############################################################################## statement1 && statement2 # and operator statement1 || statement2 # or operator -a # and operator inside a test conditional expression -o # or operator inside a test conditional expression # STRINGS str1 == str2 # str1 matches str2 str1 != str2 # str1 does not match str2 str1 < str2 # str1 is less than str2 (alphabetically) str1 > str2 # str1 is greater than str2 (alphabetically) str1 \> str2 # str1 is sorted after str2 str1 \< str2 # str1 is sorted before str2 -n str1 # str1 is not null (has length greater than 0) -z str1 # str1 is null (has length 0) # FILES -a file # file exists or its compilation is successful -d file # file exists and is a directory -e file # file exists; same -a -f file # file exists and is a regular file (i.e., not a directory or other special type of file) -r file # you have read permission -s file # file exists and is not empty -w file # your have write permission -x file # you have execute permission on file, or directory search permission if it is a directory -N file # file was modified since it was last read -O file # you own file -G file # file's group ID matches yours (or one of yours, if you are in multiple groups) file1 -nt file2 # file1 is newer than file2 file1 -ot file2 # file1 is older than file2 # NUMBERS -lt # less than -le # less than or equal -eq # equal -ge # greater than or equal -gt # greater than -ne # not equal if condition then statements [elif condition then statements...] [else statements] fi for x in {1..10} do statements done for name [in list] do statements that can use $name done for (( initialisation ; ending condition ; update )) do statements... done case expression in pattern1 ) statements ;; pattern2 ) statements ;; esac select name [in list] do statements that can use $name done while condition; do statements done until condition; do statements done ############################################################################## # COMMAND-LINE PROCESSING CYCLE ############################################################################## # The default order for command lookup is functions, followed by built-ins, with scripts and executables last. # There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`. command # removes alias and function lookup. Only built-ins and commands found in the search path are executed builtin # looks up only built-in commands, ignoring functions and commands found in PATH enable # enables and disables shell built-ins eval # takes arguments and run them through the command-line processing steps all over again ############################################################################## # INPUT/OUTPUT REDIRECTORS ############################################################################## cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 < file # takes standard input from file > file # directs standard output to file >> file # directs standard output to file; append to file if it already exists >|file # forces standard output to file even if noclobber is set n>|file # forces output to file from file descriptor n even if noclobber is set <> file # uses file as both standard input and standard output n<>file # uses file as both input and output for file descriptor n n>file # directs file descriptor n to file n<file # takes file descriptor n from file n>>file # directs file description n to file; append to file if it already exists n>& # duplicates standard output to file descriptor n n<& # duplicates standard input from file descriptor n n>&m # file descriptor n is made to be a copy of the output file descriptor n<&m # file descriptor n is made to be a copy of the input file descriptor &>file # directs standard output and standard error to file <&- # closes the standard input >&- # closes the standard output n>&- # closes the ouput from file descriptor n n<&- # closes the input from file descripor n |tee <file># output command to both terminal and a file (-a to append to file) ############################################################################## # PROCESS HANDLING ############################################################################## # To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y. # This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal. # Of course, to interrupt a job, type CTRL+C. myCommand & # runs job in the background and prompts back the shell jobs # lists all jobs (use with -l to see associated PID) fg # brings a background job into the foreground fg %+ # brings most recently invoked background job fg %- # brings second most recently invoked background job fg %N # brings job number N fg %string # brings job whose command begins with string fg %?string # brings job whose command contains string kill -l # returns a list of all signals on the system, by name and number kill PID # terminates process with specified PID kill -s SIGKILL 4500 # sends a signal to force or terminate the process kill -15 913 # Ending PID 913 process with signal 15 (TERM) kill %1 # Where %1 is the number of job as read from 'jobs' command. ps # prints a line of information about the current running login shell and any processes running under it ps -a # selects all processes with a tty except session leaders trap cmd sig1 sig2 # executes a command when a signal is received by the script trap "" sig1 sig2 # ignores that signals trap - sig1 sig2 # resets the action taken when the signal is received to the default disown <PID|JID> # removes the process from the list of jobs wait # waits until all background jobs have finished sleep <number> # wait # of seconds before continuing pv # display progress bar for data handling commands. often used with pipe like |pv yes # give yes response everytime an input is requested from script/process ############################################################################## # TIPS & TRICKS ############################################################################## # set an alias cd; nano .bash_profile > alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile # to quickly go to a specific directory cd; nano .bashrc > shopt -s cdable_vars > export websites="/Users/mac/Documents/websites" source .bashrc cd $websites ############################################################################## # DEBUGGING SHELL PROGRAMS ############################################################################## bash -n scriptname # don't run commands; check for syntax errors only set -o noexec # alternative (set option in script) bash -v scriptname # echo commands before running them set -o verbose # alternative (set option in script) bash -x scriptname # echo commands after command-line processing set -o xtrace # alternative (set option in script) trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits function errtrap { es=$? echo "ERROR line $1: Command exited with status $es." } trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status function dbgtrap { echo "badvar is $badvar" } trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script # ...section of code in which the problem occurs... trap - DEBUG # turn off the DEBUG trap function returntrap { echo "A return occurred" } trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing ############################################################################## # COLORS AND BACKGROUNDS ############################################################################## # note: \e or \x1B also work instead of \033 # Reset Color_Off='\033[0m' # Text Reset # Regular Colors Black='\033[0;30m' # Black Red='\033[0;31m' # Red Green='\033[0;32m' # Green Yellow='\033[0;33m' # Yellow Blue='\033[0;34m' # Blue Purple='\033[0;35m' # Purple Cyan='\033[0;36m' # Cyan White='\033[0;97m' # White # Additional colors LGrey='\033[0;37m' # Ligth Gray DGrey='\033[0;90m' # Dark Gray LRed='\033[0;91m' # Ligth Red LGreen='\033[0;92m' # Ligth Green LYellow='\033[0;93m'# Ligth Yellow LBlue='\033[0;94m' # Ligth Blue LPurple='\033[0;95m'# Light Purple LCyan='\033[0;96m' # Ligth Cyan # Bold BBlack='\033[1;30m' # Black BRed='\033[1;31m' # Red BGreen='\033[1;32m' # Green BYellow='\033[1;33m'# Yellow BBlue='\033[1;34m' # Blue BPurple='\033[1;35m'# Purple BCyan='\033[1;36m' # Cyan BWhite='\033[1;37m' # White # Underline UBlack='\033[4;30m' # Black URed='\033[4;31m' # Red UGreen='\033[4;32m' # Green UYellow='\033[4;33m'# Yellow UBlue='\033[4;34m' # Blue UPurple='\033[4;35m'# Purple UCyan='\033[4;36m' # Cyan UWhite='\033[4;37m' # White # Background On_Black='\033[40m' # Black On_Red='\033[41m' # Red On_Green='\033[42m' # Green On_Yellow='\033[43m'# Yellow On_Blue='\033[44m' # Blue On_Purple='\033[45m'# Purple On_Cyan='\033[46m' # Cyan On_White='\033[47m' # White # Example of usage echo -e "${Green}This is GREEN text${Color_Off} and normal text" echo -e "${Red}${On_White}This is Red test on White background${Color_Off}" # option -e is mandatory, it enable interpretation of backslash escapes printf "${Red} This is red \n"
    https://bgoonz-blog.netlify.app/images/code.png
  • vscode-themes
    vscode-themes My Favorite VSCode Themes Themes My Favorite VSCode Themes Product Icon Themes: Fluent Icons A product icon theme for Visual Studio Code Product icons themes allow theme authors to customize the icons used in VS Code's built-in views: all icons except file icons (covered by file icon themes) and icons contributed by extensions. This extension uses Fluent Icons. Install Install the icon theme from the Marketplace Open the command palette ( Ctrl/Cmd + Shift + P) and search for Preferences: Product Icon Theme Select Fluent Icons TBC… Monokai Oblique by pushqrdx Monokai inspired theme for Visual Studio Code and Visual Studio IDE.### Monokai Pro by monokai (commercial) Beautiful functionality for professional developers, from the author of the original Monokai color scheme.### Night Owl by Sarah Drasner A VS Code theme for the night owls out there. Works well in the daytime, too, but this theme is fine-tuned for those of us who like to code late into the night. Color choices have taken into consideration what is accessible to people with color blindness and in low-light circumstances. Decisions were also based on meaningful contrast for reading comprehension and for optimal razzle dazzle. ✨### Plastic by Will Stone A simple theme.### Nord by arcticicestudio An arctic, north-bluish clean and elegant Visual Studio Code theme.### Rainglow by Dayle Rees Collection of 320+ beautiful syntax and UI themes.### Relaxed Theme by Michael Kühnel A relaxed theme to take a more relaxed view of things.### Shades of Purple by Ahmad Awais⚡ A professional theme with hand-picked & bold shades of purple 💜 to go along with your VS Code. A custom VS Code theme with style.### 2077 theme by Endormi Cyberpunk 2077 inspired theme### An Old Hope Theme by Dustin Sanders VSCode theme inspired by a galaxy far far away…### Ariake Dark by wart Dark VSCode theme inspired by Japanese traditional colors and the poetry composed 1000 years ago.### Atom One Dark Theme by Mahmoud Ali One Dark Theme based on Atom.### Atomize by emroussel A detailed and accurate Atom One Dark Theme.### Ayu by teabyii A simple theme with bright colors and comes in three versions — dark, light and mirage for all day long comfortable work.### Borealis Theme by Alexander Eckert VS Code theme inspired by the calm colors of the aurora borealis in Alaska.### Captain Sweetheart by ultradracula Tuff but sweet theme.### City Lights by Yummygum🏙 Yummygum's Official City Lights suite### Cobalt2 Theme Official by Wes Bos🔥 Official theme by Wes Bos.### Dracula Official by Dracula Theme Official Dracula Theme. A dark theme for many editors, shells, and more.### Edge by Bogdan Lazar A simple theme with bright colors in three variants — Night Sky, Serene and Ocean for all day long comfortable work.### Eva Theme by fisheva A colorful and semantic coloring code theme.### Fairy Floss by nopjmp and sailorhg A fun, purple-based pastel/candy/daydream fairyfloss theme made by sailorhg.### GitHub Theme by Thomas Pink GitHub Theme for Visual Studio Code.### Jellybeans Theme by Dimitar Nonov Jellybeans Theme for Visual Studio Code.### Material Palenight Theme by whizkydee An elegant and juicy material-like theme for Visual Studio Code.### Material Theme by Mattia Astorino The most epic theme now for Visual Studio Code.### Mno by u29dc Minimal monochrome theme.### Slime Theme by smlombardi A dark syntax/workbench theme for Visual Studio Code — optimized for SCSS, HTML, JS, TS, Markdown, and PHP files.### Niketa Theme by Dejan Toteff Collection of 18 light themes separated in 4 groups by background's brightness.### If you found this guide helpful feel free to checkout my GitHub/gists where I host similar content: bgoonz's gists Instantly share code, notes, and snippets. Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python |… gist.github.com bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com By Bryan Guner on March 18, 2021. Canonical link Exported from Medium on August 6, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Understanding PATH Understanding PATH When you run a command like python or pip, your operating system searches through a list of directories to find an executable file with that name. This list of directories lives in an environment variable called PATH, with each directory in the list separated by a colon: Directories in PATH are searched from left to right, so a matching executable in a directory at the beginning of the list takes precedence over another one at the end. In this example, the /usr/local/bin directory will be searched first, then /usr/bin, then /bin. Understanding Shims pyenv works by inserting a directory of shims at the front of your PATH: Through a process called rehashing, pyenv maintains shims in that directory to match every Python command across every installed version of Python---python, pip, and so on. Shims are lightweight executables that simply pass your command along to pyenv. So with pyenv installed, when you run, say, pip, your operating system will do the following: Search your PATH for an executable file named pip Find the pyenv shim named pip at the beginning of your PATH Run the shim named pip, which in turn passes the command along to pyenv Choosing the Python Version When you execute a shim, pyenv determines which Python version to use by reading it from the following sources, in this order: The PYENV_VERSION environment variable (if specified). You can use the pyenv shell command to set this environment variable in your current shell session. The application-specific .python-version file in the current directory (if present). You can modify the current directory's .python-version file with the pyenv local command. The first .python-version file found (if any) by searching each parent directory, until reaching the root of your filesystem. The global $(pyenv root)/version file. You can modify this file using the pyenv global command. If the global version file is not present, pyenv assumes you want to use the "system" Python. (In other words, whatever version would run if pyenv weren't in your PATH.) NOTE: You can activate multiple versions at the same time, including multiple versions of Python2 or Python3 simultaneously. This allows for parallel usage of Python2 and Python3, and is required with tools like tox. For example, to set your path to first use your system Python and Python3 (set to 2.7.9 and 3.4.2 in this example), but also have Python 3.3.6, 3.2, and 2.5 available on your PATH, one would first pyenv install the missing versions, then set pyenv global system 3.3.6 3.2 2.5. At this point, one should be able to find the full executable path to each of these using pyenv which, e.g. pyenv which python2.5 (should display $(pyenv root)/versions/2.5/bin/python2.5), or pyenv which python3.4 (should display path to system Python3). You can also specify multiple versions in a .python-version file, separated by newlines. Lines starting with a # are ignored. Locating the Python Installation Once pyenv has determined which version of Python your application has specified, it passes the command along to the corresponding Python installation. Each Python version is installed into its own directory under $(pyenv root)/versions. For example, you might have these versions installed:$(pyenv root)/versions/2.7.8/$(pyenv root)/versions/3.4.2/$(pyenv root)/versions/pypy-2.4.0/ As far as Pyenv is concerned, version names are simply directories under $(pyenv root)/versions. Managing Virtual Environments There is a pyenv plugin named pyenv-virtualenv which comes with various features to help pyenv users to manage virtual environments created by virtualenv or Anaconda. Because the activate script of those virtual environments are relying on mutating $PATH variable of user's interactive shell, it will intercept pyenv's shim style command execution hooks. We'd recommend to install pyenv-virtualenv as well if you have some plan to play with those virtual environments.
    https://bgoonz-blog.netlify.app/images/code.png
  • Top Repos
    Top Repos My Top Repos / Websites: Python Practice Lambda Bootcamp Website React Notes Project Showcase Data Structures & Algorithms Lambda Site Static Content Server Mini-Project Showcase Useful Snippets Markdown Templates Zumzi Video Conferencing App (mesibo api backend) https://pages.databricks.com/rs/094-YMS-629/images/dynamic-time-warping-background.html
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Quick Links Gitbook Websites: Python General Blockchain & NFTs React Sites I Wish To Revisit: Hasura
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Pull Request Template Pull Requests Objective Description 1-3 (Not Passing) 4 (Passing) 5-7 (Exceptional) Clearly documents the motivation and what changed Is it clear why the pull request exists? Does it link to supporting documentation (user story, product roadmap, design) to give broader context? Is the code itself appropriately commented? The PR description is either blank or only contains the boilerplate PR template or unchecked checklist items. Code comments aren't used, even when they would be helpful. The PR description outlines the motivation for the feature and/or links to a user story or other document describing the purpose of the feature. The PR description includes a clear rationale for the feature, or a screenshot showing either the intended state or completed state of the feature, and gives additional context about changes made in the PR. Atomic, well-named commits Does the pull request consist of small commits with clear titles? Do all commits have relevant and sensible messages of what was changed? Commits are not named appropriately. Commits have sensible messages. Example. "Updated", "Fixed a bug" Commits are well named. Commits have descriptive messages relevant to what changed. Some commits are not atomic. Commits are well named. Commits have descriptive messages. Each commit introduces atomic changes. Appropriately Scoped Is the pull request small enough to review easily? Is it focused on solving a single cohesive problem? Pull request introduces multiple features or solves multiple problems. PR is unreasonably big with many changed files. Some code changes that are not related to the purpose of the PR PR is relatively small. PR has some minor changes not related to the feature or primary change being introduced. PR is focused on a single problem. PR is small enough and easy to review. Adequately reviewed Has the pull request been reviewed by at least two team members? Your release manager will be the final reviewer of the pull request. Did they leave any comments or suggestions? Were those suggestions acted on? PR was merged by the same developer who requested it. The reviewer rejected PR with no comments. PR was initiated again and suggested changes were not addressed. At least two team members reviewed PRs. Appropriate comments were left in the PR. Suggestions were acted upon. PRs were reviewed by more than one team member. PR requests were sent to multiple reviewers. Active high-quality discussions are evident in PRs. Code is clear and maintainable Is the code formatted appropriately? Is there dead code? logs and print statements have no place in your main branches! Are there instances of duplicate code? Does code have TODOs committed to main? Code has inconsistent formatting. Significant amount of dead code across the codebase. Multiple instances on TODOs in main. Significant amount of duplicated code. Code is consistently formatted. Functions are relatively small. Few instances of duplicate code. Few instances of dead code. Code is consistently formatted. Has config files to enforce linting and formatting. No instance on duplicate code. Code is idiomatic Does the code follow industry standards for the language, framework, and libraries used? Code consistently does not adhere to best practices for the language, framework or libraries used. Code has apparent minor deviations from industry standards. Code follows best practices of language, framework and libraries use. Effort has been made to improve on those practices.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    PostgreSQL Setup PostgreSQL Setup For Windows & WSL/Ubuntu This is an embedded Microsoft Office presentation, powered by Office. If you follow this guide to a tee… you will install PostgreSQL itself on your Windows installation. Then, you will install psql in your… PostgreSQL Setup For Windows & WSL/Ubuntu If you follow this guide to a tee… you will install PostgreSQL itself on your Windows installation. Then, you will install `psql` in your Ubuntu installation. Then you will also install Postbird, a cross-platform graphical user interface that makes working with SQL and PostgreSQL 'allegedly' …(personally I prefer to just use the command line but PG Admin makes for an immeasurably more complicated tutorial than postbird)… better than just using the **command line tool** `psql`**.** Important Distinction: PSQL is the frontend interface for PostgreSQL … they are not synonymous! Postgres, is a free and open-source relational database management system (RDBMS) PSQL: The primary front-end for PostgreSQL is the psql command-line program, which can be used to enter SQL queries directly, or execute them from a file. In addition, psql provides a number of meta-commands and various shell-like features to facilitate writing scripts and automating a wide variety of tasks; for example tab completion of object names and SQL syntax. pgAdmin: The pgAdmin package is a free and open-source graphical user interface (GUI) administration tool for PostgreSQL. When you read “installation”, that means the actual OS that's running on your machine. So, you have a Windows installation, Windows 10, that's running when you boot your computer. Then, when you start the Ubuntu installation, it's as if there's a completely separate computer running inside your computer. It's like having two completely different laptops. Other Noteworthy Distinctions:### Installing PostgreSQL 12 To install PostgreSQL 12, you need to download the installer from the Internet. PostgreSQL's commercial company, Enterprise DB, offers installers for PostgreSQL for every major platform. Open https://www.enterprisedb.com/downloads/postgres-postgresql-downloads. Click the link for PostgreSQL 12 for Windows x86–64. Once that installer downloads, run it. You need to go through the normal steps of installing software. Yes, Windows, let the installer make changes to my device. Thanks for the welcome. Next. Yeah, that's a good place to install it. Next. I don't want that pgAdmin nor the Stack Builder things. Uncheck. Uncheck. Next.- Also, great looking directory. Thanks. Next. Oooh! A password! I'll enter ****. I sure won't forget that because, if I do, I'll have to uninstall and reinstall PostgreSQL and lose all of my hard work. Seriously, write down this password or use one you will not forget!!!!!!!!!!!!!!! I REALLY CANNOT STRESS THE ABOVE POINT ENOUGH… Experience is a great teacher but in this case … it's not worth it. Sure. 5432. Good to go. Next. Not even sure what that means. Default! Next. Yep. Looks good. Next. Insert pop culture reference to pass the time Installing PostgreSQL Client Tools on Ubuntu Now, to install the PostgreSQL Client tools for Ubuntu. You need to do this so that the Node.js (and later Python) programs running on your Ubuntu installation can access the PostgreSQL server running on your Windows installation. You need to tell apt, the package manager, that you want it to go find the PostgreSQL 12 client tools from PostgreSQL itself rather than the common package repositories. You do that by issuing the following two commands. Copy and paste them one at a time into your shell. (If your Ubuntu shell isn't running, start one.) Pro-tip: Copy those commands because you're not going to type them, right? After you copy one of them, you can just right-click on the Ubuntu shell. That should paste them in there for you. wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - If prompted for your password, type it. echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list The last line of output of those two commands running should read “OK”. If it does not, try copying and pasting them one at a time. Now that you've registered the PostgreSQL repositories as a source to look for PostgreSQL, you need to update the apt registry. You should do this before you install any software on Ubuntu. sudo apt update Once that's finished running, the new entries for PostgreSQL 12 should be in the repository. Now, you can install them with the following command. sudo apt install postgresql-client-12 postgresql-common If it asks you if you want to install them, please tell it “Y”. Test that it installed by typing psql --version. You should see it print out information about the version of the installed tools. If it tells you that it can't find the command, try these instructions over. Configuring the client tools Since you're going to be accessing the PosgreSQL installation from your Ubuntu installation on your Windows installation, you're going to have to type that you want to access it over and over, which means extra typing. To prevent you from having to do this, you can customize your shell to always add the extra commands for you. This assumes you're still using Bash. If you changed the shell that your Ubuntu installation uses, please follow that shell's directions for adding an alias to its startup file. Make sure you're in your Ubuntu home directory. You can do that by typing cd and hitting enter. Use ls to find out if you have a .bashrc file. Type ls .bashrc. If it shows you that one exists, that's the one you will add the alias to. If it tells you that there is no file named that, then type ls .profile. If it shows you that one exists, that's the one you will add the alias to. If it shows you that it does not exist, then use the file name .bashrc in the following section. Now that you know which profile file to use, type code «profile file name» where "profile file name" is the name of the file you determined from the last section. Once Visual Studio Code starts up with your file, at the end of it (or if you've already added aliases, in that section), type the following. alias psql="psql -h localhost" When you run psql from the command line, it will now always add the part about wanting to connect to localhost every time. You would have to type that each time, otherwise. To make sure that you set that up correctly, type psql -U postgres postgres. This tells the psql client that you want to connect as the user "postgres" (-U postgres) to the database postgres ( postgres at the end), which is the default database created when PostgreSQL is installed. It will prompt you for a password. Type the password that you used when you installed PostgrSQL, earlier. If the alias works correctly and you type the correct password, then you should see something like the following output. psql (12.2 (Ubuntu 12.2-2.pgdg18.04+1)) Type "help" for help. postgres=# Type \q and hit Enter to exit the PostgreSQL client tool. Now, you will add a user for your Ubuntu identity so that you don't have to specify it all the time. Then, you will create a file that PostgreSQL will use to automatically send your password every time. Copy and paste the following into your Ubuntu shell. Think of a password that you want to use for your user. Replace the password in the single quotes in the command with the password that you want. It has to be a non-empty string. PostgreSQL doesn't like it when it's not. psql -U postgres -c "CREATE USER `whoami` WITH PASSWORD 'password' SUPERUSER" It should prompt you for a password. Type the password that you created when you installed PostgreSQL. Once you type the correct password, you should see “CREATE ROLE”. Now you will create your PostgreSQL password file. Type the following into your Ubuntu shell to open Visual Studio Code and create a new file. code ~/.pgpass In that file, you will add this line, which tells it that on localhost for port 5432 (where PostgreSQL is running), for all databases (*), use your Ubuntu user name and the password that you just created for that user with the psql command you just typed. (If you have forgotten your Ubuntu user name, type whoami on the command line.) Your entry in the file should have this format. localhost:5432:*:«your Ubuntu user name»:«the password you just used» Once you have that information in the file, save it, and close Visual Studio Code. The last step you have to take is change the permission on that file so that it is only readable by your user. PostgreSQL will ignore it if just anyone can read and write to it. This is for your security. Change the file permissions so only you can read and write to it. You did this once upon a time. Here's the command. chmod go-rw ~/.pgpass You can confirm that only you have read/write permission by typing ls -al ~/.pgpass. That should return output that looks like this, with your Ubuntu user name instead of "web-dev-hub".-rw------- 1 web-dev-hub web-dev-hub 37 Mar 28 21:20 /home/web-dev-hub/.pgpass Now, try connecting to PostreSQL by typing psql postgres. Because you added the alias to your startup script, and because you created your .pgpass file, it should now connect without prompting you for any credentials! Type \q and press Enter to exit the PostgreSQL command line client. Installing Postbird Head over to the Postbird releases page on GitHub. Click the installer for Windows which you can recognize because it's the only file in the list that ends with “.exe”. After that installer downloads, run it. You will get a warning from Windows that this is from an unidentified developer. If you don't want to install this, find a PostgreSQL GUI client that you do trust and install it or do everything from the command line. You should get used to seeing this because many open-source applications aren't signed with the Microsoft Store for monetary and philosophical reasons. Otherwise, if you trust Paxa like web-dev-hub and tens of thousands of other developers do, then click the link that reads “More info” and the “Run anyway” button. When it's done installing, it will launch itself. Test it out by typing the “postgres” into the “Username” field and the password from your installation in the “Password” field. Click the Connect button. It should properly connect to the running You can close it for now. It also installed an icon on your desktop. You can launch it from there or your Start Menu at any time. Now.. if you still have some gas in the tank… let's put our new tools to work: The node-postgres The node-postgres is a collection of Node.js modules for interfacing with the PostgreSQL database. It has support for callbacks, promises, async/await, connection pooling, prepared statements, cursors, and streaming results. In our examples we also use the Ramda library. See Ramda tutorial for more information. Setting up node-postgres First, we install node-postgres.$ node -v v14.2$ npm init -y We initiate a new Node application. npm i pg We install node-postgres with nmp i pg. npm i ramda In addition, we install Ramda for beautiful work with data. cars.sql DROP TABLE IF EXISTS cars; CREATE TABLE cars(id SERIAL PRIMARY KEY, name VARCHAR(255), price INT); INSERT INTO cars(name, price) VALUES('Audi', 52642); INSERT INTO cars(name, price) VALUES('Mercedes', 57127); INSERT INTO cars(name, price) VALUES('Skoda', 9000); INSERT INTO cars(name, price) VALUES('Volvo', 29000); INSERT INTO cars(name, price) VALUES('Bentley', 350000); INSERT INTO cars(name, price) VALUES('Citroen', 21000); INSERT INTO cars(name, price) VALUES('Hummer', 41400); INSERT INTO cars(name, price) VALUES('Volkswagen', 21600); In some of the examples, we use this cars table. The node-postgres first example In the first example, we connect to the PostgreSQL database and return a simple SELECT query result. first.js const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT 1 + 4').then(res => { const result = R.head(R.values(R.head(res.rows))) console.log(result) }).finally(() => client.end()); The example connects to the database and issues a SELECT statement. const pg = require('pg'); const R = require('ramda'); We include the pg and ramda modules. const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; This is the PostgreSQL connection string. It is used to build a connection to the database. const client = new pg.Client(cs); client.connect(); A client is created. We connect to the database with connect(). client.query('SELECT 1 + 4').then(res => { const result = R.head(R.values(R.head(res.rows))); console.log(result); }).finally(() => client.end()); We issue a simple SELECT query. We get the result and output it to the console. The res.rows is an array of objects; we use Ramda to get the returned scalar value. In the end, we close the connection with end(). node first.js 5 This is the output. The node-postgres column names In the following example, we get the columns names of a database. column_names.js const pg = require('pg'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT * FROM cars').then(res => { const fields = res.fields.map(field => field.name); console.log(fields); }).catch(err => { console.log(err.stack); }).finally(() => { client.end() }); The column names are retrieved with res.fields attribute. We also use the catch clause to output potential errors. node column_names.js 'id', 'name', 'price'′id′,′name′,′price′ The output shows three column names of the cars table. Selecting all rows In the next example, we select all rows from the database table. all_rows.js const pg = require('pg'); const R = require('ramda'); const cs = 'postgres://postgres:s$cret@localhost:5432/ydb'; const client = new pg.Client(cs); client.connect(); client.query('SELECT * FROM cars').then(res => { const data = res.rows; console.log('all data'); data.forEach(row => { console.log(\`Id: ${row.id} Name: ${row.name} Price: ${row.price}\`); }) console.log('Sorted prices:'); const prices = R.pluck('price', R.sortBy(R.prop('price'), data)); console.log(prices); }).finally(() => { client.end() }); TBC… If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: Stackbit Web-Dev-HubTheme Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of… bgoonz-blog.netlify.app By Bryan Guner on March 6, 2021. Canonical link Exported from Medium on August 6, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • new-repo-git
    new-repo-git...or create a new repository on the command line echo "# React-Self-Study" >> README.md git init git add README.md git commit -m "first commit" git branch -M master git remote add origin https://github.com/bgoonz/React-Self-Study.git git push -u origin master ...or push an existing repository from the command line git remote add origin https://github.com/bgoonz/React-Self-Study.git git branch -M master git push -u origin master ...or import code from another repository You can initialize this repository with code from a Subversion, Mercurial, or TFS project.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    How To Minify Code For Better Web Performance In production, it is recommended to minify any JavaScript code that is included with your application. Minification can help your website load several times faster, especially as the size of your JavaScript source code grows. Here's one way to set it up: Install Node.js Run npm init -y in your project folder ( don't skip this step!) Run npm install terser Now, to minify a file called like_button.js, run in the terminal: This will produce a file called like_button.min.js with the minified code in the same directory. If you're typing this often, you can create an npm script to give this command a name. How to Minify Your Minify your HTML, CSS and JavaScript Using an Online Tool Many of these online tools have a similar process which involve the following steps: Paste in your source code or upload the source code file. Optimize the settings for a specific output (if options are available) Click a button to minify or compress the code. Copy the minified code output or download the minified code file. For this example, I'm going to use the minify tools from minifycode.com. First, locate the css file (commonly named style.css) in your site files and open the file using a page editor. Then copy the entire css code to your clipboard. Go to minifycode.com and click the CSS minifier tab. Then paste the CSS code into the input box and click the Minify CSS button. After the new minified code is generated, copy the code. Then go back to the css file of your website and replace the code with the new minified version. That's it! Repeat the same process to minify your site's JavaScript and Html file(s) as well. Overview Minification refers to the process of removing unnecessary or redundant data without affecting how the resource is processed by the browser - e.g. code comments and formatting, removing unused code, using shorter variable and function names, and so on. See preprocessing & context-specific optimizations to learn more. Recommendations You should minify your HTML, CSS, and JavaScript resources: To minify HTML, try HTMLMinifier To minify CSS, try CSSNano and csso. To minify JavaScript, try UglifyJS. The Closure Compiler is also very effective. You can create a build process that uses these tools to minify and rename the development files and save them to a production directory. Alternatively, the PageSpeed Module, integrates with an Apache or Nginx web server to automatically optimize your site, including resource minification.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Markdown Dropdown Markdown Dropdown: How do I dropdown? This is how you dropdown. <details> <summary>How do I dropdown?</summary> <br> This is how you dropdown. </details> Want to ruin the surprise? Well, you asked for it! <details open> <summary>Want to ruin the surprise?</summary> <br> Well, you asked for it! </details>
    https://bgoonz-blog.netlify.app/images/code.png
  • Installation
    Installation Basic Web Development Environment Setup Windows Subsystem for Linux (WSL) and Ubuntu Windows Subsystem for Linux (WSL) and Ubuntu Test if you have Ubuntu installed by typing “Ubuntu” in the search box in the bottom app bar that reads “Type here to search”. If you see a search result that reads “Ubuntu 20.04 LTS” with “App” under it, then you have it installed. In the application search box in the bottom bar, type “PowerShell” to find the application named “Windows PowerShell” Right-click on “Windows PowerShell” and choose “Run as administrator” from the popup menu In the blue PowerShell window, type the following: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux Restart your computer In the application search box in the bottom bar, type “Store” to find the application named “Microsoft Store” Click “Microsoft Store” Click the “Search” button in the upper-right corner of the window Type in “Ubuntu” Click “Run Linux on Windows (Get the apps)” Click the orange tile labeled “Ubuntu” Note that there are 3 versions in the Microsoft Store… you want the one just entitled 'Ubuntu' Click “Install” After it downloads, click “Launch” If you get the option, pin the application to the task bar. Otherwise, right-click on the orange Ubuntu icon in the task bar and choose “Pin to taskbar” When prompted to “Enter new UNIX username”, type your first name with no spaces When prompted, enter and retype a password for this UNIX user (it can be the same as your Windows password) Confirm your installation by typing the command whoami 'as in who-am-i' followed by Enter at the prompt (it should print your first name) You need to update your packages, so type sudo apt update (if prompted for your password, enter it) You need to upgrade your packages, so type sudo apt upgrade (if prompted for your password, enter it) Git comes with Ubuntu, so there's nothing to install. However, you should configure it using the following instructions.‌Open an Ubuntu terminal if you don't have one open already. You need to configure Git, so type git config --global user.name "Your Name" with replacing "Your Name" with your real name. You need to configure Git, so type git config --global user.email your@email.com with replacing " your@email.com" with your real email. Note: if you want git to remember your login credentials type:$ git config --global credential.helper store Test if you have Chrome installed by typing “Chrome” in the search box in the bottom app bar that reads “Type here to search”. If you see a search result that reads “Chrome” with “App” under it, then you have it installed. Otherwise, follow these instructions to install Google Chrome. Open Microsoft Edge, the blue “e” in the task bar, and type in http://chrome.google.com. Click the “Download Chrome” button. Click the “Accept and Install” button after reading the terms of service. Click “Save” in the “What do you want to do with ChromeSetup.exe” dialog at the bottom of the window. When you have the option to “Run” it, do so. Answer the questions as you'd like. Set it as the default browser. Right-click on the Chrome icon in the task bar and choose “Pin to taskbar”. Test if you have Node.js installed by opening an Ubuntu terminal and typing node --version. If it reports "Command 'node' not found", then you need to follow these directions. In the Ubuntu terminal, type sudo apt update and press Enter In the Ubuntu terminal, type sudo apt install build-essential and press Enter In the Ubuntu terminal, type curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash and press Enter In the Ubuntu terminal, type . ./.bashrc and press Enter In the Ubuntu terminal, type nvm install --lts and press Enter Confirm that node is installed by typing node --version and seeing it print something that is not "Command not found"! You will often have to download a zip file and unzip it. It is easier to do this from the command line. So we need to install a linux unzip utility.‌In the Ubuntu terminal type: sudo apt install unzip and press Enter‌Mocha.js Test if you have Mocha.js installed by opening an Ubuntu terminal and typing which mocha. If it prints a path, then you're good. Otherwise, if it prints nothing, install Mocha.js by typing npm install -g mocha. Ubuntu does not come with Python 3. Install it using the command sudo apt install python3. Test it by typing python3 --version and seeing it print a number.‌ As of the time of writing of this document, WSL has an issue renaming or deleting files if Visual Studio Code is open. So before doing any linux commands which manipulate files, make sure you close Visual Studio Code before running those commands in the Ubuntu terminal.# Installing build essentials sudo apt-get install -y build-essential libssl-dev # Nodejs and NVM curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash source ~/.profile sudo nvm install 7.10.0 sudo nvm use 7.10.0 node -v nodemon sudo npm install -g nodemon sudo npm install -g loopback-cli # Forever to run nodejs scripts forever sudo npm install forever -g # Git - a version control system sudo apt-get update sudo apt-get install -y git xclip # Grunt - an automated task runner sudo npm install -g grunt-cli # Bower - a dependency manager sudo npm install -g bower # Yeoman - for generators sudo npm install -g yo # maven sudo apt-get install maven -y # Gulp - an automated task runner sudo npm install -g gulp-cli # Angular FullStack - My favorite MEAN boilerplate (MEAN = MongoDB, Express, Angularjs, Nodejs) sudo npm install -g generator-angular-fullstack # Vim, Curl, Python - Some random useful stuff sudo apt-get install -y vim curl python-software-properties sudo apt-get install -y python-dev, python-pip sudo apt-get install -y libkrb5-dev # Installing JDK and JRE sudo apt-get install -y default-jre sudo apt-get install -y default-jdk # Archive Extractors sudo apt-get install -y unace unrar zip unzip p7zip-full p7zip-rar sharutils rar uudeview mpack arj cabextract file-roller # FileZilla - a FTP client sudo apt-get install -y filezilla If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub Or Checkout my personal Resource Site: Source
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Heroku Error Codes Heroku Error Codes Last updated August 04, 2021 Table of Contents H10 - App crashed H11 - Backlog too deep H12 - Request timeout H13 - Connection closed without response H14 - No web dynos running H15 - Idle connection H16 - (No Longer in Use) H17 - Poorly formatted HTTP response H18 - Server Request Interrupted H19 - Backend connection timeout H20 - App boot timeout H21 - Backend connection refused H22 - Connection limit reached H23 - Endpoint misconfigured H24 - Forced close H25 - HTTP Restriction H26 - Request Error H27 - Client Request Interrupted H28 - Client Connection Idle H31 - Misdirected Request H80 - Maintenance mode H81 - Blank app H82 - Free dyno quota exhausted H99 - Platform error R10 - Boot timeout R12 - Exit timeout R13 - Attach error R14 - Memory quota exceeded R15 - Memory quota vastly exceeded R16 - Detached R17 - Checksum error R99 - Platform error L10 - Drain buffer overflow L11 - Tail buffer overflow L12 - Local buffer overflow L13 - Local delivery error L14 - Certificate validation error L15 - Tail buffer temporarily unavailable Whenever your app experiences an error, Heroku will return a standard error page with the HTTP status code 503. To help you debug the underlying error, however, the platform will also add custom error information to your logs. Each type of error gets its own error code, with all HTTP errors starting with the letter H and all runtime errors starting with R. Logging errors start with L. H10 - App crashed A crashed web dyno or a boot timeout on the web dyno will present this error. 2010-10-06T21:51:04-07:00 heroku[web.1]: State changed from down to starting 2010-10-06T21:51:07-07:00 app[web.1]: Starting process with command: `bundle exec rails server -p 22020` 2010-10-06T21:51:09-07:00 app[web.1]: >> Using rails adapter 2010-10-06T21:51:09-07:00 app[web.1]: Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed. 2010-10-06T21:51:10-07:00 heroku[web.1]: Process exited 2010-10-06T21:51:12-07:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H11 - Backlog too deep When HTTP requests arrive faster than your application can process them, they can form a large backlog on a number of routers. When the backlog on a particular router passes a threshold, the router determines that your application isn't keeping up with its incoming request volume. You'll see an H11 error for each incoming request as long as the backlog is over this size. The exact value of this threshold may change depending on various factors, such as the number of dynos in your app, response time for individual requests, and your app's normal request volume. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H11 desc="Backlog too deep" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= The solution is to increase your app's throughput by adding more dynos, tuning your database (for example, adding an index), or making the code itself faster. As always, increasing performance is highly application-specific and requires profiling. H12 - Request timeout For more information on request timeouts (including recommendations for resolving them), take a look at our article on the topic. An HTTP request took longer than 30 seconds to complete. In the example below, a Rails app takes 37 seconds to render the page; the HTTP router returns a 503 prior to Rails completing its request cycle, but the Rails process continues and the completion message shows after the router message. 2010-10-06T21:51:07-07:00 app[web.2]: Processing PostController#list (for 75.36.147.245 at 2010-10-06 21:51:07) [GET] 2010-10-06T21:51:08-07:00 app[web.2]: Rendering template within layouts/application 2010-10-06T21:51:19-07:00 app[web.2]: Rendering post/list 2010-10-06T21:51:37-07:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=6ms service=30001ms status=503 bytes=0 2010-10-06T21:51:42-07:00 app[web.2]: Completed in 37000ms (View: 27, DB: 21) | 200 OK [http://myapp.heroku.com/] This 30-second limit is measured by the router, and includes all time spent in the dyno, including the kernel's incoming connection queue and the app itself. See Request Timeout for more, as well as a language-specific article on this error: H12 - Request Timeout in Ruby (MRI) H13 - Connection closed without response This error is thrown when a process in your web dyno accepts a connection but then closes the socket without writing anything to it. 2010-10-06T21:51:37-07:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=3030ms service=9767ms status=503 bytes=0 One example where this might happen is when a Unicorn web server is configured with a timeout shorter than 30s and a request has not been processed by a worker before the timeout happens. In this case, Unicorn closes the connection before any data is written, resulting in an H13. An example of an H13 can be found here. H14 - No web dynos running This is most likely the result of scaling your web dynos down to 0 dynos. To fix it, scale your web dynos to 1 or more dynos:$ heroku ps:scale web=1 Use the heroku ps command to determine the state of your web dynos. 2010-10-06T21:51:37-07:00 heroku[router]: at=error code=H14 desc="No web processes running" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H15 - Idle connection The dyno did not send a full response and was terminated due to 55 seconds of inactivity. For example, the response indicated a Content-Length of 50 bytes which were not sent in time. 2010-10-06T21:51:37-07:00 heroku[router]: at=error code=H15 desc="Idle connection" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=55449ms status=503 bytes=18 H16 - (No Longer in Use) Heroku no longer emits H16 errors H17 - Poorly formatted HTTP response Our HTTP routing stack has no longer accepts responses that are missing a reason phrase in the status line. 'HTTP/1.1 200 OK' will work with the new router, but 'HTTP/1.1 200' will not. This error message is logged when a router detects a malformed HTTP response coming from a dyno. 2010-10-06T21:51:37-07:00 heroku[router]: at=error code=H17 desc="Poorly formatted HTTP response" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=1ms status=503 bytes=0 H18 - Server Request Interrupted An H18 signifies that the socket connected, some data was sent as part of a response by the app, but then the socket was destroyed without completing the response. 2010-10-06T21:51:37-07:00 heroku[router]: sock=backend at=error code=H18 desc="Server Request Interrupted" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=1ms status=503 bytes=0 An example of an H18 can be found here. H19 - Backend connection timeout A router received a connection timeout error after 5 seconds attempting to open a socket to a web dyno. This is usually a symptom of your app being overwhelmed and failing to accept new connections in a timely manner. If you have multiple dynos, the router will retry multiple dynos before logging H19 and serving a standard error page. If your app has a single web dyno, it is possible to see H19 errors if the runtime instance running your web dyno fails and is replaced. Once the failure is detected and the instance is terminated your web dyno will be restarted somewhere else, but in the meantime, H19s may be served as the router fails to establish a connection to your dyno. This can be mitigated by running more than one web dyno. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H19 desc="Backend connection timeout" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=5001ms service= status=503 bytes= H20 - App boot timeout The router will enqueue requests for 75 seconds while waiting for starting processes to reach an "up" state. If after 75 seconds, no web dynos have reached an "up" state, the router logs H20 and serves a standard error page. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H20 desc="App boot timeout" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= The Ruby on Rails asset pipeline can sometimes fail to run during git push, and will instead attempt to run when your app's dynos boot. Since the Rails asset pipeline is a slow process, this can cause H20 boot timeout errors. This error differs from R10 in that the H20 75-second timeout includes platform tasks such as internal state propagation, requests between internal components, slug download, unpacking, container preparation, etc... The R10 60-second timeout applies solely to application startup tasks. If your application requires more time to boot, you may use the boot timeout tool to increase the limit. However, in general, slow boot times will make it harder to deploy your application and will make recovery from dyno failures slower, so this should be considered a temporary solution. H21 - Backend connection refused A router received a connection refused error when attempting to open a socket to your web process. This is usually a symptom of your app being overwhelmed and failing to accept new connections. If you have multiple dynos, the router will retry multiple dynos before logging H21 and serving a standard error page. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H21 desc="Backend connection refused" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service= status=503 bytes= H22 - Connection limit reached A routing node has detected an elevated number of HTTP client connections attempting to reach your app. Reaching this threshold most likely means your app is under heavy load and is not responding quickly enough to keep up. The exact value of this threshold may change depending on various factors, such as the number of dynos in your app, response time for individual requests, and your app's normal request volume. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H22 desc="Connection limit reached" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H23 - Endpoint misconfigured A routing node has detected a websocket handshake, specifically the 'Sec-Websocket-Version' header in the request, that came from an endpoint (upstream proxy) that does not support websockets. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H23 desc="Endpoint misconfigured" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H24 - Forced close The routing node serving this request was either shutdown for maintenance or terminated before the request completed. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H24 desc="Forced close" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=80000ms status= bytes=18 H25 - HTTP Restriction This error is logged when a routing node detects and blocks a valid HTTP response that is judged risky or too large to be safely parsed. The error comes in four types. Currently, this functionality is experimental, and is only made available to a subset of applications on the platform. Invalid content length The response has multiple content lengths declared within the same response, with varying lengths. 2014-03-20T14:22:00.203382+00:00 heroku[router]: at=error code=H25 desc="HTTP restriction: invalid content length" method=GET path="/" host=myapp.herokuapp.com request_id=3f336f1a-9be3-4791-afe3-596a1f2a481f fwd="17.17.17.17" dyno=web.1 connect=0 service=1 status=502 bytes=537 Oversized cookies The cookie in the response will be too large to be used again in a request to the Heroku router or SSL endpoints. 2014-03-20T14:18:57.403882+00:00 heroku[router]: at=error code=H25 desc="HTTP restriction: oversized cookie" method=GET path="/" host=myapp.herokuapp.com request_id=90cfbbd2-0397-4bab-828f-193050a076c4 fwd="17.17.17.17" dyno=web.1 connect=0 service=2 status=502 bytes=537 Oversized header A single header line is deemed too long (over 512kb) and the response is discarded on purpose. 2014-03-20T14:12:28.555073+00:00 heroku[router]: at=error code=H25 desc="HTTP restriction: oversized header" method=GET path="/" host=myapp.herokuapp.com request_id=ab66646e-84eb-47b8-b3bb-2031ecc1bc2c fwd="17.17.17.17" dyno=web.1 connect=0 service=397 status=502 bytes=542 Oversized status line The status line is judged too long (8kb) and the response is discarded on purpose. 2014-03-20T13:54:44.423083+00:00 heroku[router]: at=error code=H25 desc="HTTP restriction: oversized status line" method=GET path="/" host=myapp.herokuapp.com request_id=208588ac-1a66-44c1-b665-fe60c596241b fwd="17.17.17.17" dyno=web.1 connect=0 service=3 status=502 bytes=537 H26 - Request Error This error is logged when a request has been identified as belonging to a specific Heroku application, but cannot be delivered entirely to a dyno due to HTTP protocol errors in the request. Multiple possible causes can be identified in the log message. Unsupported expect header value The request has an expect header, and its value is not 100-Continue, the only expect value handled by the router. A request with an unsupported expect value is terminated with the status code 417 Expectation Failed. 2014-05-14T17:17:37.456997+00:00 heroku[router]: at=error code=H26 desc="Request Error" cause="unsupported expect header value" method=GET path="/" host=myapp.herokuapp.com request_id=3f336f1a-9be3-4791-afe3-596a1f2a481f fwd="17.17.17.17" dyno= connect= service= status=417 bytes= Bad header The request has an HTTP header with a value that is either impossible to parse, or not handled by the router, such as connection: ,. 2014-05-14T17:17:37.456997+00:00 heroku[router]: at=error code=H26 desc="Request Error" cause="bad header" method=GET path="/" host=myapp.herokuapp.com request_id=3f336f1a-9be3-4791-afe3-596a1f2a481f fwd="17.17.17.17" dyno= connect= service= status=400 bytes= Bad chunk The request has a chunked transfer-encoding, but with a chunk that was invalid or couldn't be parsed correctly. A request with this status code will be interrupted during transfer to the dyno. 2014-05-14T17:17:37.456997+00:00 heroku[router]: at=error code=H26 desc="Request Error" cause="bad chunk" method=GET path="/" host=myapp.herokuapp.com request_id=3f336f1a-9be3-4791-afe3-596a1f2a481f fwd="17.17.17.17" dyno=web.1 connect=1 service=0 status=400 bytes=537 H27 - Client Request Interrupted The client socket was closed either in the middle of the request or before a response could be returned. For example, the client closed their browser session before the request was able to complete. 2010-10-06T21:51:37-07:00 heroku[router]: sock=client at=warning code=H27 desc="Client Request Interrupted" method=POST path="/submit/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=0ms status=499 bytes=0 H28 - Client Connection Idle The client did not send a full request and was terminated due to 55 seconds of inactivity. For example, the client indicated a Content-Length of 50 bytes which were not sent in time. 2010-10-06T21:51:37-07:00 heroku[router]: at=warning code=H28 desc="Client Connection Idle" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno=web.1 connect=1ms service=55449ms status=499 bytes=18 H31 - Misdirected Request The client sent a request to the wrong endpoint. This could be because the client used stale DNS information or is accessing the app through a CDN that has stale DNS information. Verify that DNS is correctly configured for your app. If a CDN is configured for the app, consider contacting your CDN provider. If you and your app users can successfully access the app in a browser (or however the app is used), this may not be cause for concern. The errors may be caused by clients (typically web-crawlers) with cached DNS entries trying to access a now-invalid endpoint or IP address for your app. You can verify the validity of user agent through the app log error message as shown in the example below: error code=H31 desc="Misdirected Request" method=GET path="/" host=[host.com] request_id=[guid] fwd="[IP]" dyno= connect= service= status=421 bytes= protocol=http agent="<agent>" H80 - Maintenance mode This is not an error, but we give it a code for the sake of completeness. Note the log formatting is the same but without the word "Error". 2010-10-06T21:51:07-07:00 heroku[router]: at=info code=H80 desc="Maintenance mode" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H81 - Blank app No code has been pushed to this application. To get rid of this message you need to do one deploy. This is not an error, but we give it a code for the sake of completeness. 2010-10-06T21:51:07-07:00 heroku[router]: at=info code=H81 desc="Blank app" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H82 - Free dyno quota exhausted This indicates that an account's free dyno hour quota is exhausted and that apps running free dynos are sleeping. You can view your app's free dyno usage in the Heroku dashboard. 2015-10-06T21:51:07-07:00 heroku[router]: at=info code=H82 desc="Free dyno quota exhausted" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= H99 - Platform error H99 and R99 are the only error codes that represent errors in the Heroku platform. This indicates an internal error in the Heroku platform. Unlike all of the other errors which will require action from you to correct, this one does not require action from you. Try again in a minute, or check the status site. 2010-10-06T21:51:07-07:00 heroku[router]: at=error code=H99 desc="Platform error" method=GET path="/" host=myapp.herokuapp.com fwd=17.17.17.17 dyno= connect= service= status=503 bytes= R10 - Boot timeout A web process took longer than 60 seconds to bind to its assigned $PORT. When this happens, the dyno's process is killed and the dyno is considered crashed. Crashed dynos are restarted according to the dyno manager's restart policy. 2011-05-03T17:31:38+00:00 heroku[web.1]: State changed from created to starting 2011-05-03T17:31:40+00:00 heroku[web.1]: Starting process with command: `bundle exec rails server -p 22020 -e production` 2011-05-03T17:32:40+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch 2011-05-03T17:32:40+00:00 heroku[web.1]: Stopping process with SIGKILL 2011-05-03T17:32:40+00:00 heroku[web.1]: Process exited 2011-05-03T17:32:41+00:00 heroku[web.1]: State changed from starting to crashed This error is often caused by a process being unable to reach an external resource, such as a database, or the application doing too much work, such as parsing and evaluating numerous, large code dependencies, during startup. Common solutions are to access external resources asynchronously, so they don't block startup, and to reduce the amount of application code or its dependencies. If your application requires more time to boot, you may use the boot timeout tool to increase the limit. However, in general, slow boot times will make it harder to deploy your application and will make recovery from dyno failures slower, so this should be considered a temporary solution. One exception is for apps using the Java buildpack, Gradle buildpack, heroku-deploy toolbelt plugin, or Heroku Maven plugin, which will be allowed 90 seconds to bind to their assigned port. R12 - Exit timeout A process failed to exit within 30 seconds of being sent a SIGTERM indicating that it should stop. The process is sent SIGKILL to force an exit. 2011-05-03T17:40:10+00:00 app[worker.1]: Working 2011-05-03T17:40:11+00:00 heroku[worker.1]: Stopping process with SIGTERM 2011-05-03T17:40:11+00:00 app[worker.1]: Ignoring SIGTERM 2011-05-03T17:40:14+00:00 app[worker.1]: Working 2011-05-03T17:40:18+00:00 app[worker.1]: Working 2011-05-03T17:40:21+00:00 heroku[worker.1]: Error R12 (Exit timeout) -> Process failed to exit within 30 seconds of SIGTERM 2011-05-03T17:40:21+00:00 heroku[worker.1]: Stopping process with SIGKILL 2011-05-03T17:40:21+00:00 heroku[worker.1]: Process exited R13 - Attach error A dyno started with heroku run failed to attach to the invoking client. 2011-06-29T02:13:29+00:00 app[run.3]: Awaiting client 2011-06-29T02:13:30+00:00 heroku[run.3]: State changed from starting to up 2011-06-29T02:13:59+00:00 app[run.3]: Error R13 (Attach error) -> Failed to attach to process 2011-06-29T02:13:59+00:00 heroku[run.3]: Process exited R14 - Memory quota exceeded A dyno requires memory in excess of its quota. If this error occurs, the dyno will page to swap space to continue running, which may cause degraded process performance. The R14 error is calculated by total memory swap, rss and cache. 2011-05-03T17:40:10+00:00 app[worker.1]: Working 2011-05-03T17:40:10+00:00 heroku[worker.1]: Process running mem=1028MB(103.3%) 2011-05-03T17:40:11+00:00 heroku[worker.1]: Error R14 (Memory quota exceeded) 2011-05-03T17:41:52+00:00 app[worker.1]: Working If you are getting a large number of R14 errors, your application performance is likely severely degraded. Resolving R14 memory errors are language specific: R14 - Memory Quota Exceeded in Ruby (MRI) Troubleshooting Memory Issues in Java Applications Troubleshooting Node.js Memory Use R15 - Memory quota vastly exceeded A dyno requires vastly more memory than its quota and is consuming excessive swap space. If this error occurs, the dyno will be forcibly killed with SIGKILL (which cannot be caught or handled) by the platform. The R15 error is calculated by total memory swap and rss; cache is not included. 2011-05-03T17:40:10+00:00 app[worker.1]: Working 2011-05-03T17:40:10+00:00 heroku[worker.1]: Process running mem=1029MB(201.0%) 2011-05-03T17:40:11+00:00 heroku[worker.1]: Error R15 (Memory quota vastly exceeded) 2011-05-03T17:40:11+00:00 heroku[worker.1]: Stopping process with SIGKILL 2011-05-03T17:40:12+00:00 heroku[worker.1]: Process exited In Private Spaces, dynos exceeding their memory quota do not use swap space and thus do not emit R14 errors. Private Space dynos vastly exceeding their memory quota generally will emit R15 errors but occasionally the platform may shut down the dyno before the R15 is sent, causing the error to be dropped. If an R15 is emitted it will only be visible in the app log stream but not in the dashboard Application Metrics interface. Other non-R15 types of errors from Private Space dynos are correctly surfaced in the Application Metrics interface. For Private Space dynos vastly exceeding their memory quota the platform kills dyno processes consuming large amounts of memory, but may not kill the dyno itself. R16 - Detached An attached dyno is continuing to run after being sent SIGHUP when its external connection was closed. This is usually a mistake, though some apps might want to do this intentionally. 2011-05-03T17:32:03+00:00 heroku[run.1]: Awaiting client 2011-05-03T17:32:03+00:00 heroku[run.1]: Starting process with command `bash` 2011-05-03T17:40:11+00:00 heroku[run.1]: Client connection closed. Sending SIGHUP to all processes 2011-05-03T17:40:16+00:00 heroku[run.1]: Client connection closed. Sending SIGHUP to all processes 2011-05-03T17:40:21+00:00 heroku[run.1]: Client connection closed. Sending SIGHUP to all processes 2011-05-03T17:40:26+00:00 heroku[run.1]: Error R16 (Detached) -> An attached process is not responding to SIGHUP after its external connection was closed. R17 - Checksum error This indicates an error with runtime slug checksum verification. If the checksum does not match or there is another problem with the checksum when launch a dyno, an R17 error will occur and the dyno will fail to launch. Check the log stream for details about the error. 2016-08-16T12:39:56.439438+00:00 heroku[web.1]: State changed from provisioning to starting 2016-08-16T12:39:57.110759+00:00 heroku[web.1]: Error R17 (Checksum error) -> Checksum does match expected value. Expected: SHA256:ed5718e83475c780145609cbb2e4f77ec8076f6f59ebc8a916fb790fbdb1ae64 Actual: SHA256:9ca15af16e06625dfd123ebc3472afb0c5091645512b31ac3dd355f0d8cc42c1 2016-08-16T12:39:57.212053+00:00 heroku[web.1]: State changed from starting to crashed If this error occurs, try deploying a new release with a correct checksum or rolling back to an older release. Ensure the checksum is formatted and calculated correctly with the SHA256 algorithm. The checksum must start with SHA256: followed by the calculated SHA256 value for the compressed slug. If you did not manually calculate the checksum and error continues to occur, please contact Heroku support. R99 - Platform error R99 and H99 are the only error codes that represent errors in the Heroku platform. This indicates an internal error in the Heroku platform. Unlike all of the other errors which will require action from you to correct, this one does not require action from you. Try again in a minute, or check the status site. L10 - Drain buffer overflow 2013-04-17T19:04:46+00:00 d.1234-drain-identifier-567 heroku logplex - - Error L10 (output buffer overflow): 500 messages dropped since 2013-04-17T19:04:46+00:00. The number of log messages being generated has temporarily exceeded the rate at which they can be received by a drain consumer (such as a log management add-on) and Logplex, Heroku's logging system, has discarded some messages in order to handle the rate difference. A common cause of L10 error messages is the exhaustion of capacity in a log consumer. If a log management add-on or similar system can only accept so many messages per time period, your application may experience L10s after crossing that threshold. Another common cause of L10 error messages is a sudden burst of log messages from a dyno. As each line of dyno output (e.g. a line of a stack trace) is a single log message, and Logplex limits the total number of un-transmitted log messages it will keep in memory to 1024 messages, a burst of lines from a dyno can overflow buffers in Logplex. In order to allow the log stream to catch up, Logplex will discard messages where necessary, keeping newer messages in favor of older ones. You may need to investigate reducing the volume of log lines output by your application (e.g. condense multiple log lines into a smaller, single-line entry). You can also use the heroku logs -t command to get a live feed of logs and find out where your problem might be. A single dyno stuck in a loop that generates log messages can force an L10 error, as can a problematic code path that causes all dynos to generate a multi-line stack trace for some code paths. L11 - Tail buffer overflow A heroku logs --tail session cannot keep up with the volume of logs generated by the application or log channel, and Logplex has discarded some log lines necessary to catch up. To avoid this error you will need run the command on a faster internet connection (increase the rate at which you can receive logs) or you will need to modify your application to reduce the logging volume (decrease the rate at which logs are generated). 2011-05-03T17:40:10+00:00 heroku[logplex]: L11 (Tail buffer overflow) -> This tail session dropped 1101 messages since 2011-05-03T17:35:00+00:00 L12 - Local buffer overflow The application is producing logs faster than the local delivery process (log-shuttle) can deliver them to logplex and has discarded some log lines in order to keep up. If this error is sustained you will need to reduce the logging volume of your application. 2013-11-04T21:31:32.125756+00:00 app[log-shuttle]: Error L12: 222 messages dropped since 2013-11-04T21:31:32.125756+00:00. L13 - Local delivery error The local log delivery process (log-shuttle) was unable to deliver some logs to Logplex and has discarded them. This can happen during transient network errors or during logplex service degradation. If this error is sustained please contact support. 2013-11-04T21:31:32.125756+00:00 app[log-shuttle]: Error L13: 111 messages lost since 2013-11-04T21:31:32.125756+00:00. L14 - Certificate validation error The application is configured with a TLS syslog drain that doesn't have a valid TLS certificate. You should check that: You're not using a self-signed certificate. The certificate is up to date. The certificate is signed by a known and trusted CA. The CN hostname embedded in the certificate matches the hostname being connected to. 2015-09-04T23:28:48+00:00 heroku[logplex]: Error L14 (certificate validation): error="bad certificate" uri="syslog+tls://logs.example.com:6514/" L15 - Tail buffer temporarily unavailable The tail buffer that stores the last 1500 lines of your logs is temporarily unavailable. Run heroku logs again. If you still encounter the error, run heroku logs -t to stream your logs (which does not use the tail buffer).
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Firebase (Firebasics) Add Firebase to your JavaScript project Note: Upgrading from the version 8 Firebase SDK? Check out our upgrade guide.#### Create a Firebase project Note: Using the v9 SDK is strongly recommended, especially for production apps. If you need support for other SDK management options, like window.firebase, see Upgrade from version 8 to the modular Web SDK. Note: You can skip this step if you are using a JavaScript framework CLI tool like the Angular CLI, Next.js, Vue CLI, or Create React App. Check out our guide on module bundling for more information. Follow this guide to use the Firebase JavaScript SDK in your web app or as a client for end-user access, for example, in a Node.js desktop or IoT application. Step 1: Create a Firebase project and register your app Before you can add Firebase to your JavaScript app, you need to create a Firebase project and register your app with that project. When you register your app with Firebase, you'll get a Firebase configuration object that you'll use to connect your app with your Firebase project resources. Visit Understand Firebase Projects to learn more about Firebase projects and best practices for adding apps to projects. If you don't already have a JavaScript project and just want to try out a Firebase product, you can download one of our quickstart samples. Step 2: Install the SDK and initialize Firebase This page describes setup instructions for version 9 of the Firebase JS SDK, which uses a JavaScript Module format. This workflow uses npm and requires module bundlers or JavaScript framework tooling because the v9 SDK is optimized to work with module bundlers to eliminate unused code (tree-shaking) and decrease SDK size. Install Firebase using npm: Initialize Firebase in your app and create a Firebase App object: A Firebase App is a container-like object that stores common configuration and shares authentication across Firebase services. After you initialize a Firebase App object in your code, you can add and start using Firebase services. Do you use ESM and want to use browser modules? Replace all your import lines to use the following pattern: import { } from ' https://www.gstatic.com/firebasejs/9.0.2/firebase-SERVICE.js'(where SERVICE is an SDK name such as firebase-firestore). Using browser modules is a quick way to get started, but we recommend using a module bundler for production. Step 3: Access Firebase in your app Firebase services (like Cloud Firestore, Authentication, Realtime Database, Remote Config, and more) are available to import within individual sub-packages. The example below shows how you could use the Cloud Firestore Lite SDK to retrieve a list of data. Step 4: Use a module bundler (webpack/Rollup) for size reduction The Firebase Web SDK is designed to work with module bundlers to remove any unused code (tree-shaking). We strongly recommend using this approach for production apps. Tools such as the Angular CLI, Next.js, Vue CLI, or Create React App automatically handle module bundling for libraries installed through npm and imported into your codebase. See our guide Using module bundlers with Firebase for more information.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Git Tricks Useful config 🔗 branch.autosetuprebase=always ( documentation): I find it easier to work with Git this way core.editor=emacs -nw ( documentation): that's the editor that will be invoked every time Git needs to ask you about a commit message, when you're squashing commits, etc (and of course, you want emacs for that) commit.gpgsign=true ( documentation) and gpg.program=gpg2 ( documentation): you will need to set up these variables (and possibly a couple other) if you want to sign your commits to GitHub using GPG (recommended) Safest way to “update” a local copy 🔗 I find this sequence of commands the “safest” way to quickly “refresh” a clone of some remote repo, and at the same time check its status (where “safest” means “reducing to the minimum the probability of messing up things with conflicts, outdated branches, uncommitted changes, etc”):$ git branch -a displays information about all branches, both local and remote$ git pull -r fetches changes from the remote and “rebases the current branch on top of the upstream branch after fetching”$ git status shows you the status of your copy: whether there are new files, missing files, unstaged changes, or commits pending push$ git remote prune origin --dry tells you if any branch in the remote has been recently removed. (Submit the same command without the --dry part to actually remove those remotes from your local origin. That will still not remove local branches automatically, but you can do that yourself with git branch -d <BRANCH> if you see some branch is no longer necessary.) You can have those four lines as an alias, or inside a script somewhere. Even better: if you set up the aliases suggested above, the whole thing becomes: You can then type it and run it just once, and, from that moment on, simply recover the line from your shell history. For example, if you're using Bash: press Ctrl+r, then start typing a distinctive chunk of the line (eg, r;, or st;gi); if you used it not too long ago for the last time, the entire line should appear, and you can simply press Enter. An alias to view the history of the repo 🔗 Then, simply type for a colourful graph of commits, tags and branches.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Git Bash Git Bash‌‌‌‌‌‌‌‌‌‌‌‌‌‌‌ At its core, Git is a set of command line utility programs that are designed to execute on a Unix style command-line environment. Modern operating systems like Linux and macOS both include built-in Unix command line terminals. This makes Linux and macOS complementary operating systems when working with Git. Microsoft Windows instead uses Windows command prompt, a non-Unix terminal environment. In Windows environments, Git is often packaged as part of higher level GUI applications. GUIs for Git may attempt to abstract and hide the underlying version control system primitives. This can be a great aid for Git beginners to rapidly contribute to a project. Once a project's collaboration requirements grow with other team members, it is critical to be aware of how the actual raw Git methods work. This is when it can be beneficial to drop a GUI version for the command line tools. Git Bash is offered to provide a terminal Git experience. What is Git Bash? Git Bash is an application for Microsoft Windows environments which provides an emulation layer for a Git command line experience. Bash is an acronym for Bourne Again Shell. A shell is a terminal application used to interface with an operating system through written commands. Bash is a popular default shell on Linux and macOS. Git Bash is a package that installs Bash, some common bash utilities, and Git on a Windows operating system. How to install Git Bash Git Bash comes included as part of the Git For Windows package. Download and install Git For Windows like other Windows applications. Once downloaded find the included .exe file and open to execute Git Bash. How to use Git Bash Git Bash has the same operations as a standard Bash experience. It will be helpful to review basic Bash usage. Advanced usage of Bash is outside the scope of this Git focused document. How to navigate folders The Bash command pwd is used to print the 'present working directory'. pwd is equivalent to executing cd on a DOS(Windows console host) terminal. This is the folder or path that the current Bash session resides in. The Bash command ls is used to 'list' contents of the current working directory. ls is equivalent to DIR on a Windows console host terminal. Both Bash and Windows console host have a cd command. cd is an acronym for 'Change Directory'. cd is invoked with an appended directory name. Executing cd will change the terminal sessions current working directory to the passed directory argument. Git Bash Commands Git Bash is packaged with additional commands that can be found in the /usr/bin directory of the Git Bash emulation. Git Bash can actually provide a fairly robust shell experience on Windows. Git Bash comes packaged with the following shell commands which are outside the scope of this document: Ssh, scp, cat, find. In addition the previously discussed set of Bash commands, Git Bash includes the full set of Git core commands discussed through out this site. Learn more at the corresponding documentation pages for git clone, git commit, git checkout, git push, and more.
    https://bgoonz-blog.netlify.app/images/code.png
  • Emmet Cheat Sheet
    Emmet Cheat Sheet Emmet Cheat Sheet EMMET Emmet Cheat Sheet EMMET The a toolkit for web-developers Introduction Emmet is a productivity toolkit for web developers that uses expressions to generate HTML snippets. Installation Normally, installation for Emmet should be a straight-forward process from the package-manager, as most of the modern text editors support Emmet. Usage You can use Emmet in two ways: Tab Expand Way: Type your emmet code and press Tab key Interactive Method: Press alt + ctrl + Enter and start typing your expressions. This should automatically generate HTML snippets on the fly. This cheatsheet will assume that you press Tab after each expressions. HTML Generating HTML 5 DOCTYPE html:5 Will generate<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> </html> Child items Child items are created using > ul>li>p<ul> <li> <p></p> </li> </ul> Sibling Items Sibling items are created using + html>head+body<html> <head></head> <body> </body> </html> Multiplication Items can be multiplied by * ul>li*5<ul> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> Grouping Items can be grouped together using () table>(tr>th*5)+tr>t*5<table> <tr> <th></th> <th></th> <th></th> <th></th> <th></th> </tr> <tr> <t></t> <t></t> <t></t> <t></t> <t></t> </tr> </table> Class and ID Class and Id in Emmet can be done using . and # div.heading<div class="heading"></div> div#heading<div id="heading"></div> ID and Class can also be combined together div#heading.center<div id="heading" class="center"></div> Adding Content inside tags Contents inside tags can be added using {} h1{Emmet is awesome}+h2{Every front end developers should use this}+p{This is paragraph}*2<h1>Emmet is awesome</h1> <h2>Every front end developers should use this</h2> <p>This is paragraph</p> <p>This is paragraph</p> Attributes inside HTML tags Attributes can be added using [] a[href=https://?google.com data-toggle=something target=_blank]<a href="https://?google.com" data-toggle="something" target="_blank"></a> Numbering Numbering can be done using $ You can use this inside tag or contents. h${This is so awesome $}*6<h1>This is so awesome 1</h1> <h2>This is so awesome 2</h2> <h3>This is so awesome 3</h3> <h4>This is so awesome 4</h4> <h5>This is so awesome 5</h5> <h6>This is so awesome 6</h6> Use @- to reverse the Numbering img[src=image$$@-.jpg]*5<img src="image05.jpg" alt=""> <img src="image04.jpg" alt=""> <img src="image03.jpg" alt=""> <img src="image02.jpg" alt=""> <img src="image01.jpg" alt=""> To start the numbering from specific number, use this way img[src=emmet$@100.jpg]*5<img src="emmet100.jpg" alt=""> <img src="emmet101.jpg" alt=""> <img src="emmet102.jpg" alt=""> <img src="emmet103.jpg" alt=""> <img src="emmet104.jpg" alt=""> Tips Use : to expand known abbreviations input:date<input type="date" name="" id=""> form:post<form action="" method="post"></form> link:css<link rel="stylesheet" href="style.css"> Building Navbar.navbar>ul>li*3>a[href=#]{Item $@-}<div class="navbar"> <ul> <li><a href="#">Item 3</a></li> <li><a href="#">Item 2</a></li> <li><a href="#">Item 1</a></li> </ul> </div> CSS Emmet works surprisingly well with css as well. f:l float: left; You can also use any options n/r/l pos:a­ position: absolute; Also use any options, pos:a/r/f d:n/b­/f/­i/ib d:ib display: inline-block; You can use m for margin and p for padding followed by direction mr -> margin-right pr -> padding-right@f will result in@font-face { font-family:; src:url(); } You can also use these shorthands#### If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: a/A-Student-Resources Edit description goofy-euclid-1cd736.netlify.app By Bryan Guner on March 6, 2021. Canonical link Exported from Medium on May 23, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Getting Started W Create React App Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: yarn start Runs the app in the development mode. Open http://localhost:3000 to view it in the browser. The page will reload if you make edits. You will also see any lint errors in the console. yarn test Launches the test runner in the interactive watch mode. See the section about running tests for more information. yarn build Builds the app for production to the build folder. It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes. Your app is ready to be deployed! See the section about deployment for more information. yarn eject Note: this is a one-way operation. Once you eject, you can't go back! If you aren't satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project. Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. You don't have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. Learn More You can learn more in the Create React App documentation. To learn React, check out the React documentation. Code Splitting This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting Analyzing the Bundle Size This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size Making a Progressive Web App This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app Advanced Configuration This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration Deployment This section has moved here: https://facebook.github.io/create-react-app/docs/deployment yarn build fails to minify This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    All Emojis All Emojis😀 😃 😄 😁 😆 😅 😂 🤣 🥲 ☺️ 😊 😇 🙂 🙃 😉 😌 😍 🥰 😘 😗 😙 😚 😋 😛 😝 😜 🤪 🤨 🧐 🤓 😎 🥸 🤩 🥳 😏 😒 😞 😔 😟 😕 🙁 ☹️ 😣 😖 😫 😩 🥺 😢 😭 😤 😠 😡 🤬 🤯 😳 🥵 🥶 😱 😨 😰 😥 😓 🤗 🤔 🤭 🤫 🤥 😶 😐 😑 😬 🙄 😯 😦 😧 😮 😲 🥱 😴 🤤 😪 😵 🤐 🥴 🤢 🤮 🤧 😷 🤒 🤕 🤑 🤠 😈 👿 👹 👺 🤡 💩 👻 💀 ☠️ 👽 👾 🤖 🎃 😺 😸 😹 😻 😼 😽 🙀 😿 😾 Gestures and Body Parts👋 🤚 🖐 ✋ 🖖 👌 🤌 🤏 ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍 👎 ✊ 👊 🤛 🤜 👏 🙌 👐 🤲 🤝 🙏 ✍️ 💅 🤳 💪 🦾 🦵 🦿 🦶 👣 👂 🦻 👃 🫀 🫁 🧠 🦷 🦴 👀 👁 👅 👄 💋 🩸 People and Fantasy👶 👧 🧒 👦 👩 🧑 👨 👩‍🦱 🧑‍🦱 👨‍🦱 👩‍🦰 🧑‍🦰 👨‍🦰 👱‍♀️ 👱 👱‍♂️ 👩‍🦳 🧑‍🦳 👨‍🦳 👩‍🦲 🧑‍🦲 👨‍🦲 🧔 👵 🧓 👴 👲 👳‍♀️ 👳 👳‍♂️ 🧕 👮‍♀️ 👮 👮‍♂️ 👷‍♀️ 👷 👷‍♂️ 💂‍♀️ 💂 💂‍♂️ 🕵️‍♀️ 🕵️ 🕵️‍♂️ 👩‍⚕️ 🧑‍⚕️ 👨‍⚕️ 👩‍🌾 🧑‍🌾 👨‍🌾 👩‍🍳 🧑‍🍳 👨‍🍳 👩‍🎓 🧑‍🎓 👨‍🎓 👩‍🎤 🧑‍🎤 👨‍🎤 👩‍🏫 🧑‍🏫 👨‍🏫 👩‍🏭 🧑‍🏭 👨‍🏭 👩‍💻 🧑‍💻 👨‍💻 👩‍💼 🧑‍💼 👨‍💼 👩‍🔧 🧑‍🔧 👨‍🔧 👩‍🔬 🧑‍🔬 👨‍🔬 👩‍🎨 🧑‍🎨 👨‍🎨 👩‍🚒 🧑‍🚒 👨‍🚒 👩‍✈️ 🧑‍✈️ 👨‍✈️ 👩‍🚀 🧑‍🚀 👨‍🚀 👩‍⚖️ 🧑‍⚖️ 👨‍⚖️ 👰‍♀️ 👰 👰‍♂️ 🤵‍♀️ 🤵 🤵‍♂️ 👸 🤴 🥷 🦸‍♀️ 🦸 🦸‍♂️ 🦹‍♀️ 🦹 🦹‍♂️ 🤶 🧑‍🎄 🎅 🧙‍♀️ 🧙 🧙‍♂️ 🧝‍♀️ 🧝 🧝‍♂️ 🧛‍♀️ 🧛 🧛‍♂️ 🧟‍♀️ 🧟 🧟‍♂️ 🧞‍♀️ 🧞 🧞‍♂️ 🧜‍♀️ 🧜 🧜‍♂️ 🧚‍♀️ 🧚 🧚‍♂️ 👼 🤰 🤱 👩‍🍼 🧑‍🍼 👨‍🍼 🙇‍♀️ 🙇 🙇‍♂️ 💁‍♀️ 💁 💁‍♂️ 🙅‍♀️ 🙅 🙅‍♂️ 🙆‍♀️ 🙆 🙆‍♂️ 🙋‍♀️ 🙋 🙋‍♂️ 🧏‍♀️ 🧏 🧏‍♂️ 🤦‍♀️ 🤦 🤦‍♂️ 🤷‍♀️ 🤷 🤷‍♂️ 🙎‍♀️ 🙎 🙎‍♂️ 🙍‍♀️ 🙍 🙍‍♂️ 💇‍♀️ 💇 💇‍♂️ 💆‍♀️ 💆 💆‍♂️ 🧖‍♀️ 🧖 🧖‍♂️ 💅 🤳 💃 🕺 👯‍♀️ 👯 👯‍♂️ 🕴 👩‍🦽 🧑‍🦽 👨‍🦽 👩‍🦼 🧑‍🦼 👨‍🦼 🚶‍♀️ 🚶 🚶‍♂️ 👩‍🦯 🧑‍🦯 👨‍🦯 🧎‍♀️ 🧎 🧎‍♂️ 🏃‍♀️ 🏃 🏃‍♂️ 🧍‍♀️ 🧍 🧍‍♂️ 👭 🧑‍🤝‍🧑 👬 👫 👩‍❤️‍👩 💑 👨‍❤️‍👨 👩‍❤️‍👨 👩‍❤️‍💋‍👩 💏 👨‍❤️‍💋‍👨 👩‍❤️‍💋‍👨 👪 👨‍👩‍👦 👨‍👩‍👧 👨‍👩‍👧‍👦 👨‍👩‍👦‍👦 👨‍👩‍👧‍👧 👨‍👨‍👦 👨‍👨‍👧 👨‍👨‍👧‍👦 👨‍👨‍👦‍👦 👨‍👨‍👧‍👧 👩‍👩‍👦 👩‍👩‍👧 👩‍👩‍👧‍👦 👩‍👩‍👦‍👦 👩‍👩‍👧‍👧 👨‍👦 👨‍👦‍👦 👨‍👧 👨‍👧‍👦 👨‍👧‍👧 👩‍👦 👩‍👦‍👦 👩‍👧 👩‍👧‍👦 👩‍👧‍👧 🗣 👤 👥 🫂 Clothing and Accessories🧳 🌂 ☂️ 🧵 🪡 🪢 🧶 👓 🕶 🥽 🥼 🦺 👔 👕 👖 🧣 🧤 🧥 🧦 👗 👘 🥻 🩴 🩱 🩲 🩳 👙 👚 👛 👜 👝 🎒 👞 👟 🥾 🥿 👠 👡 🩰 👢 👑 👒 🎩 🎓 🧢 ⛑ 🪖 💄 💍 💼 Pale Emojis👋🏻 🤚🏻 🖐🏻 ✋🏻 🖖🏻 👌🏻 🤌🏻 🤏🏻 ✌🏻 🤞🏻 🤟🏻 🤘🏻 🤙🏻 👈🏻 👉🏻 👆🏻 🖕🏻 👇🏻 ☝🏻 👍🏻 👎🏻 ✊🏻 👊🏻 🤛🏻 🤜🏻 👏🏻 🙌🏻 👐🏻 🤲🏻 🙏🏻 ✍🏻 💅🏻 🤳🏻 💪🏻 🦵🏻 🦶🏻 👂🏻 🦻🏻 👃🏻 👶🏻 👧🏻 🧒🏻 👦🏻 👩🏻 🧑🏻 👨🏻 👩🏻‍🦱 🧑🏻‍🦱 👨🏻‍🦱 👩🏻‍🦰 🧑🏻‍🦰 👨🏻‍🦰 👱🏻‍♀️ 👱🏻 👱🏻‍♂️ 👩🏻‍🦳 🧑🏻‍🦳 👨🏻‍🦳 👩🏻‍🦲 🧑🏻‍🦲 👨🏻‍🦲 🧔🏻 👵🏻 🧓🏻 👴🏻 👲🏻 👳🏻‍♀️ 👳🏻 👳🏻‍♂️ 🧕🏻 👮🏻‍♀️ 👮🏻 👮🏻‍♂️ 👷🏻‍♀️ 👷🏻 👷🏻‍♂️ 💂🏻‍♀️ 💂🏻 💂🏻‍♂️ 🕵🏻‍♀️ 🕵🏻 🕵🏻‍♂️ 👩🏻‍⚕️ 🧑🏻‍⚕️ 👨🏻‍⚕️ 👩🏻‍🌾 🧑🏻‍🌾 👨🏻‍🌾 👩🏻‍🍳 🧑🏻‍🍳 👨🏻‍🍳 👩🏻‍🎓 🧑🏻‍🎓 👨🏻‍🎓 👩🏻‍🎤 🧑🏻‍🎤 👨🏻‍🎤 👩🏻‍🏫 🧑🏻‍🏫 👨🏻‍🏫 👩🏻‍🏭 🧑🏻‍🏭 👨🏻‍🏭 👩🏻‍💻 🧑🏻‍💻 👨🏻‍💻 👩🏻‍💼 🧑🏻‍💼 👨🏻‍💼 👩🏻‍🔧 🧑🏻‍🔧 👨🏻‍🔧 👩🏻‍🔬 🧑🏻‍🔬 👨🏻‍🔬 👩🏻‍🎨 🧑🏻‍🎨 👨🏻‍🎨 👩🏻‍🚒 🧑🏻‍🚒 👨🏻‍🚒 👩🏻‍✈️ 🧑🏻‍✈️ 👨🏻‍✈️ 👩🏻‍🚀 🧑🏻‍🚀 👨🏻‍🚀 👩🏻‍⚖️ 🧑🏻‍⚖️ 👨🏻‍⚖️ 👰🏻‍♀️ 👰🏻 👰🏻‍♂️ 🤵🏻‍♀️ 🤵🏻 🤵🏻‍♂️ 👸🏻 🤴🏻 🥷🏻 🦸🏻‍♀️ 🦸🏻 🦸🏻‍♂️ 🦹🏻‍♀️ 🦹🏻 🦹🏻‍♂️ 🤶🏻 🧑🏻‍🎄 🎅🏻 🧙🏻‍♀️ 🧙🏻 🧙🏻‍♂️ 🧝🏻‍♀️ 🧝🏻 🧝🏻‍♂️ 🧛🏻‍♀️ 🧛🏻 🧛🏻‍♂️ 🧜🏻‍♀️ 🧜🏻 🧜🏻‍♂️ 🧚🏻‍♀️ 🧚🏻 🧚🏻‍♂️ 👼🏻 🤰🏻 🤱🏻 👩🏻‍🍼 🧑🏻‍🍼 👨🏻‍🍼 🙇🏻‍♀️ 🙇🏻 🙇🏻‍♂️ 💁🏻‍♀️ 💁🏻 💁🏻‍♂️ 🙅🏻‍♀️ 🙅🏻 🙅🏻‍♂️ 🙆🏻‍♀️ 🙆🏻 🙆🏻‍♂️ 🙋🏻‍♀️ 🙋🏻 🙋🏻‍♂️ 🧏🏻‍♀️ 🧏🏻 🧏🏻‍♂️ 🤦🏻‍♀️ 🤦🏻 🤦🏻‍♂️ 🤷🏻‍♀️ 🤷🏻 🤷🏻‍♂️ 🙎🏻‍♀️ 🙎🏻 🙎🏻‍♂️ 🙍🏻‍♀️ 🙍🏻 🙍🏻‍♂️ 💇🏻‍♀️ 💇🏻 💇🏻‍♂️ 💆🏻‍♀️ 💆🏻 💆🏻‍♂️ 🧖🏻‍♀️ 🧖🏻 🧖🏻‍♂️ 💃🏻 🕺🏻 🕴🏻 👩🏻‍🦽 🧑🏻‍🦽 👨🏻‍🦽 👩🏻‍🦼 🧑🏻‍🦼 👨🏻‍🦼 🚶🏻‍♀️ 🚶🏻 🚶🏻‍♂️ 👩🏻‍🦯 🧑🏻‍🦯 👨🏻‍🦯 🧎🏻‍♀️ 🧎🏻 🧎🏻‍♂️ 🏃🏻‍♀️ 🏃🏻 🏃🏻‍♂️ 🧍🏻‍♀️ 🧍🏻 🧍🏻‍♂️ 👭🏻 🧑🏻‍🤝‍🧑🏻 👬🏻 👫🏻 🧗🏻‍♀️ 🧗🏻 🧗🏻‍♂️ 🏇🏻 🏂🏻 🏌🏻‍♀️ 🏌🏻 🏌🏻‍♂️ 🏄🏻‍♀️ 🏄🏻 🏄🏻‍♂️ 🚣🏻‍♀️ 🚣🏻 🚣🏻‍♂️ 🏊🏻‍♀️ 🏊🏻 🏊🏻‍♂️ ⛹🏻‍♀️ ⛹🏻 ⛹🏻‍♂️ 🏋🏻‍♀️ 🏋🏻 🏋🏻‍♂️ 🚴🏻‍♀️ 🚴🏻 🚴🏻‍♂️ 🚵🏻‍♀️ 🚵🏻 🚵🏻‍♂️ 🤸🏻‍♀️ 🤸🏻 🤸🏻‍♂️ 🤽🏻‍♀️ 🤽🏻 🤽🏻‍♂️ 🤾🏻‍♀️ 🤾🏻 🤾🏻‍♂️ 🤹🏻‍♀️ 🤹🏻 🤹🏻‍♂️ 🧘🏻‍♀️ 🧘🏻 🧘🏻‍♂️ 🛀🏻 🛌🏻 Cream White Emojis👋🏼 🤚🏼 🖐🏼 ✋🏼 🖖🏼 👌🏼 🤌🏼 🤏🏼 ✌🏼 🤞🏼 🤟🏼 🤘🏼 🤙🏼 👈🏼 👉🏼 👆🏼 🖕🏼 👇🏼 ☝🏼 👍🏼 👎🏼 ✊🏼 👊🏼 🤛🏼 🤜🏼 👏🏼 🙌🏼 👐🏼 🤲🏼 🙏🏼 ✍🏼 💅🏼 🤳🏼 💪🏼 🦵🏼 🦶🏼 👂🏼 🦻🏼 👃🏼 👶🏼 👧🏼 🧒🏼 👦🏼 👩🏼 🧑🏼 👨🏼 👩🏼‍🦱 🧑🏼‍🦱 👨🏼‍🦱 👩🏼‍🦰 🧑🏼‍🦰 👨🏼‍🦰 👱🏼‍♀️ 👱🏼 👱🏼‍♂️ 👩🏼‍🦳 🧑🏼‍🦳 👨🏼‍🦳 👩🏼‍🦲 🧑🏼‍🦲 👨🏼‍🦲 🧔🏼 👵🏼 🧓🏼 👴🏼 👲🏼 👳🏼‍♀️ 👳🏼 👳🏼‍♂️ 🧕🏼 👮🏼‍♀️ 👮🏼 👮🏼‍♂️ 👷🏼‍♀️ 👷🏼 👷🏼‍♂️ 💂🏼‍♀️ 💂🏼 💂🏼‍♂️ 🕵🏼‍♀️ 🕵🏼 🕵🏼‍♂️ 👩🏼‍⚕️ 🧑🏼‍⚕️ 👨🏼‍⚕️ 👩🏼‍🌾 🧑🏼‍🌾 👨🏼‍🌾 👩🏼‍🍳 🧑🏼‍🍳 👨🏼‍🍳 👩🏼‍🎓 🧑🏼‍🎓 👨🏼‍🎓 👩🏼‍🎤 🧑🏼‍🎤 👨🏼‍🎤 👩🏼‍🏫 🧑🏼‍🏫 👨🏼‍🏫 👩🏼‍🏭 🧑🏼‍🏭 👨🏼‍🏭 👩🏼‍💻 🧑🏼‍💻 👨🏼‍💻 👩🏼‍💼 🧑🏼‍💼 👨🏼‍💼 👩🏼‍🔧 🧑🏼‍🔧 👨🏼‍🔧 👩🏼‍🔬 🧑🏼‍🔬 👨🏼‍🔬 👩🏼‍🎨 🧑🏼‍🎨 👨🏼‍🎨 👩🏼‍🚒 🧑🏼‍🚒 👨🏼‍🚒 👩🏼‍✈️ 🧑🏼‍✈️ 👨🏼‍✈️ 👩🏼‍🚀 🧑🏼‍🚀 👨🏼‍🚀 👩🏼‍⚖️ 🧑🏼‍⚖️ 👨🏼‍⚖️ 👰🏼‍♀️ 👰🏼 👰🏼‍♂️ 🤵🏼‍♀️ 🤵🏼 🤵🏼‍♂️ 👸🏼 🤴🏼 🥷🏼 🦸🏼‍♀️ 🦸🏼 🦸🏼‍♂️ 🦹🏼‍♀️ 🦹🏼 🦹🏼‍♂️ 🤶🏼 🧑🏼‍🎄 🎅🏼 🧙🏼‍♀️ 🧙🏼 🧙🏼‍♂️ 🧝🏼‍♀️ 🧝🏼 🧝🏼‍♂️ 🧛🏼‍♀️ 🧛🏼 🧛🏼‍♂️ 🧜🏼‍♀️ 🧜🏼 🧜🏼‍♂️ 🧚🏼‍♀️ 🧚🏼 🧚🏼‍♂️ 👼🏼 🤰🏼 🤱🏼 👩🏼‍🍼 🧑🏼‍🍼 👨🏼‍🍼 🙇🏼‍♀️ 🙇🏼 🙇🏼‍♂️ 💁🏼‍♀️ 💁🏼 💁🏼‍♂️ 🙅🏼‍♀️ 🙅🏼 🙅🏼‍♂️ 🙆🏼‍♀️ 🙆🏼 🙆🏼‍♂️ 🙋🏼‍♀️ 🙋🏼 🙋🏼‍♂️ 🧏🏼‍♀️ 🧏🏼 🧏🏼‍♂️ 🤦🏼‍♀️ 🤦🏼 🤦🏼‍♂️ 🤷🏼‍♀️ 🤷🏼 🤷🏼‍♂️ 🙎🏼‍♀️ 🙎🏼 🙎🏼‍♂️ 🙍🏼‍♀️ 🙍🏼 🙍🏼‍♂️ 💇🏼‍♀️ 💇🏼 💇🏼‍♂️ 💆🏼‍♀️ 💆🏼 💆🏼‍♂️ 🧖🏼‍♀️ 🧖🏼 🧖🏼‍♂️ 💃🏼 🕺🏼 🕴🏼 👩🏼‍🦽 🧑🏼‍🦽 👨🏼‍🦽 👩🏼‍🦼 🧑🏼‍🦼 👨🏼‍🦼 🚶🏼‍♀️ 🚶🏼 🚶🏼‍♂️ 👩🏼‍🦯 🧑🏼‍🦯 👨🏼‍🦯 🧎🏼‍♀️ 🧎🏼 🧎🏼‍♂️ 🏃🏼‍♀️ 🏃🏼 🏃🏼‍♂️ 🧍🏼‍♀️ 🧍🏼 🧍🏼‍♂️ 👭🏼 🧑🏼‍🤝‍🧑🏼 👬🏼 👫🏼 🧗🏼‍♀️ 🧗🏼 🧗🏼‍♂️ 🏇🏼 🏂🏼 🏌🏼‍♀️ 🏌🏼 🏌🏼‍♂️ 🏄🏼‍♀️ 🏄🏼 🏄🏼‍♂️ 🚣🏼‍♀️ 🚣🏼 🚣🏼‍♂️ 🏊🏼‍♀️ 🏊🏼 🏊🏼‍♂️ ⛹🏼‍♀️ ⛹🏼 ⛹🏼‍♂️ 🏋🏼‍♀️ 🏋🏼 🏋🏼‍♂️ 🚴🏼‍♀️ 🚴🏼 🚴🏼‍♂️ 🚵🏼‍♀️ 🚵🏼 🚵🏼‍♂️ 🤸🏼‍♀️ 🤸🏼 🤸🏼‍♂️ 🤽🏼‍♀️ 🤽🏼 🤽🏼‍♂️ 🤾🏼‍♀️ 🤾🏼 🤾🏼‍♂️ 🤹🏼‍♀️ 🤹🏼 🤹🏼‍♂️ 🧘🏼‍♀️ 🧘🏼 🧘🏼‍♂️ 🛀🏼 🛌🏼 Brown Emojis👋🏽 🤚🏽 🖐🏽 ✋🏽 🖖🏽 👌🏽 🤌🏽 🤏🏽 ✌🏽 🤞🏽 🤟🏽 🤘🏽 🤙🏽 👈🏽 👉🏽 👆🏽 🖕🏽 👇🏽 ☝🏽 👍🏽 👎🏽 ✊🏽 👊🏽 🤛🏽 🤜🏽 👏🏽 🙌🏽 👐🏽 🤲🏽 🙏🏽 ✍🏽 💅🏽 🤳🏽 💪🏽 🦵🏽 🦶🏽 👂🏽 🦻🏽 👃🏽 👶🏽 👧🏽 🧒🏽 👦🏽 👩🏽 🧑🏽 👨🏽 👩🏽‍🦱 🧑🏽‍🦱 👨🏽‍🦱 👩🏽‍🦰 🧑🏽‍🦰 👨🏽‍🦰 👱🏽‍♀️ 👱🏽 👱🏽‍♂️ 👩🏽‍🦳 🧑🏽‍🦳 👨🏽‍🦳 👩🏽‍🦲 🧑🏽‍🦲 👨🏽‍🦲 🧔🏽 👵🏽 🧓🏽 👴🏽 👲🏽 👳🏽‍♀️ 👳🏽 👳🏽‍♂️ 🧕🏽 👮🏽‍♀️ 👮🏽 👮🏽‍♂️ 👷🏽‍♀️ 👷🏽 👷🏽‍♂️ 💂🏽‍♀️ 💂🏽 💂🏽‍♂️ 🕵🏽‍♀️ 🕵🏽 🕵🏽‍♂️ 👩🏽‍⚕️ 🧑🏽‍⚕️ 👨🏽‍⚕️ 👩🏽‍🌾 🧑🏽‍🌾 👨🏽‍🌾 👩🏽‍🍳 🧑🏽‍🍳 👨🏽‍🍳 👩🏽‍🎓 🧑🏽‍🎓 👨🏽‍🎓 👩🏽‍🎤 🧑🏽‍🎤 👨🏽‍🎤 👩🏽‍🏫 🧑🏽‍🏫 👨🏽‍🏫 👩🏽‍🏭 🧑🏽‍🏭 👨🏽‍🏭 👩🏽‍💻 🧑🏽‍💻 👨🏽‍💻 👩🏽‍💼 🧑🏽‍💼 👨🏽‍💼 👩🏽‍🔧 🧑🏽‍🔧 👨🏽‍🔧 👩🏽‍🔬 🧑🏽‍🔬 👨🏽‍🔬 👩🏽‍🎨 🧑🏽‍🎨 👨🏽‍🎨 👩🏽‍🚒 🧑🏽‍🚒 👨🏽‍🚒 👩🏽‍✈️ 🧑🏽‍✈️ 👨🏽‍✈️ 👩🏽‍🚀 🧑🏽‍🚀 👨🏽‍🚀 👩🏽‍⚖️ 🧑🏽‍⚖️ 👨🏽‍⚖️ 👰🏽‍♀️ 👰🏽 👰🏽‍♂️ 🤵🏽‍♀️ 🤵🏽 🤵🏽‍♂️ 👸🏽 🤴🏽 🥷🏽 🦸🏽‍♀️ 🦸🏽 🦸🏽‍♂️ 🦹🏽‍♀️ 🦹🏽 🦹🏽‍♂️ 🤶🏽 🧑🏽‍🎄 🎅🏽 🧙🏽‍♀️ 🧙🏽 🧙🏽‍♂️ 🧝🏽‍♀️ 🧝🏽 🧝🏽‍♂️ 🧛🏽‍♀️ 🧛🏽 🧛🏽‍♂️ 🧜🏽‍♀️ 🧜🏽 🧜🏽‍♂️ 🧚🏽‍♀️ 🧚🏽 🧚🏽‍♂️ 👼🏽 🤰🏽 🤱🏽 👩🏽‍🍼 🧑🏽‍🍼 👨🏽‍🍼 🙇🏽‍♀️ 🙇🏽 🙇🏽‍♂️ 💁🏽‍♀️ 💁🏽 💁🏽‍♂️ 🙅🏽‍♀️ 🙅🏽 🙅🏽‍♂️ 🙆🏽‍♀️ 🙆🏽 🙆🏽‍♂️ 🙋🏽‍♀️ 🙋🏽 🙋🏽‍♂️ 🧏🏽‍♀️ 🧏🏽 🧏🏽‍♂️ 🤦🏽‍♀️ 🤦🏽 🤦🏽‍♂️ 🤷🏽‍♀️ 🤷🏽 🤷🏽‍♂️ 🙎🏽‍♀️ 🙎🏽 🙎🏽‍♂️ 🙍🏽‍♀️ 🙍🏽 🙍🏽‍♂️ 💇🏽‍♀️ 💇🏽 💇🏽‍♂️ 💆🏽‍♀️ 💆🏽 💆🏽‍♂️ 🧖🏽‍♀️ 🧖🏽 🧖🏽‍♂️ 💃🏽 🕺🏽 🕴🏽 👩🏽‍🦽 🧑🏽‍🦽 👨🏽‍🦽 👩🏽‍🦼 🧑🏽‍🦼 👨🏽‍🦼 🚶🏽‍♀️ 🚶🏽 🚶🏽‍♂️ 👩🏽‍🦯 🧑🏽‍🦯 👨🏽‍🦯 🧎🏽‍♀️ 🧎🏽 🧎🏽‍♂️ 🏃🏽‍♀️ 🏃🏽 🏃🏽‍♂️ 🧍🏽‍♀️ 🧍🏽 🧍🏽‍♂️ 👭🏽 🧑🏽‍🤝‍🧑🏽 👬🏽 👫🏽 🧗🏽‍♀️ 🧗🏽 🧗🏽‍♂️ 🏇🏽 🏂🏽 🏌🏽‍♀️ 🏌🏽 🏌🏽‍♂️ 🏄🏽‍♀️ 🏄🏽 🏄🏽‍♂️ 🚣🏽‍♀️ 🚣🏽 🚣🏽‍♂️ 🏊🏽‍♀️ 🏊🏽 🏊🏽‍♂️ ⛹🏽‍♀️ ⛹🏽 ⛹🏽‍♂️ 🏋🏽‍♀️ 🏋🏽 🏋🏽‍♂️ 🚴🏽‍♀️ 🚴🏽 🚴🏽‍♂️ 🚵🏽‍♀️ 🚵🏽 🚵🏽‍♂️ 🤸🏽‍♀️ 🤸🏽 🤸🏽‍♂️ 🤽🏽‍♀️ 🤽🏽 🤽🏽‍♂️ 🤾🏽‍♀️ 🤾🏽 🤾🏽‍♂️ 🤹🏽‍♀️ 🤹🏽 🤹🏽‍♂️ 🧘🏽‍♀️ 🧘🏽 🧘🏽‍♂️ 🛀🏽 🛌🏽 Dark Brown Emojis👋🏾 🤚🏾 🖐🏾 ✋🏾 🖖🏾 👌🏾 🤌🏾 🤏🏾 ✌🏾 🤞🏾 🤟🏾 🤘🏾 🤙🏾 👈🏾 👉🏾 👆🏾 🖕🏾 👇🏾 ☝🏾 👍🏾 👎🏾 ✊🏾 👊🏾 🤛🏾 🤜🏾 👏🏾 🙌🏾 👐🏾 🤲🏾 🙏🏾 ✍🏾 💅🏾 🤳🏾 💪🏾 🦵🏾 🦶🏾 👂🏾 🦻🏾 👃🏾 👶🏾 👧🏾 🧒🏾 👦🏾 👩🏾 🧑🏾 👨🏾 👩🏾‍🦱 🧑🏾‍🦱 👨🏾‍🦱 👩🏾‍🦰 🧑🏾‍🦰 👨🏾‍🦰 👱🏾‍♀️ 👱🏾 👱🏾‍♂️ 👩🏾‍🦳 🧑🏾‍🦳 👨🏾‍🦳 👩🏾‍🦲 🧑🏾‍🦲 👨🏾‍🦲 🧔🏾 👵🏾 🧓🏾 👴🏾 👲🏾 👳🏾‍♀️ 👳🏾 👳🏾‍♂️ 🧕🏾 👮🏾‍♀️ 👮🏾 👮🏾‍♂️ 👷🏾‍♀️ 👷🏾 👷🏾‍♂️ 💂🏾‍♀️ 💂🏾 💂🏾‍♂️ 🕵🏾‍♀️ 🕵🏾 🕵🏾‍♂️ 👩🏾‍⚕️ 🧑🏾‍⚕️ 👨🏾‍⚕️ 👩🏾‍🌾 🧑🏾‍🌾 👨🏾‍🌾 👩🏾‍🍳 🧑🏾‍🍳 👨🏾‍🍳 👩🏾‍🎓 🧑🏾‍🎓 👨🏾‍🎓 👩🏾‍🎤 🧑🏾‍🎤 👨🏾‍🎤 👩🏾‍🏫 🧑🏾‍🏫 👨🏾‍🏫 👩🏾‍🏭 🧑🏾‍🏭 👨🏾‍🏭 👩🏾‍💻 🧑🏾‍💻 👨🏾‍💻 👩🏾‍💼 🧑🏾‍💼 👨🏾‍💼 👩🏾‍🔧 🧑🏾‍🔧 👨🏾‍🔧 👩🏾‍🔬 🧑🏾‍🔬 👨🏾‍🔬 👩🏾‍🎨 🧑🏾‍🎨 👨🏾‍🎨 👩🏾‍🚒 🧑🏾‍🚒 👨🏾‍🚒 👩🏾‍✈️ 🧑🏾‍✈️ 👨🏾‍✈️ 👩🏾‍🚀 🧑🏾‍🚀 👨🏾‍🚀 👩🏾‍⚖️ 🧑🏾‍⚖️ 👨🏾‍⚖️ 👰🏾‍♀️ 👰🏾 👰🏾‍♂️ 🤵🏾‍♀️ 🤵🏾 🤵🏾‍♂️ 👸🏾 🤴🏾 🥷🏾 🦸🏾‍♀️ 🦸🏾 🦸🏾‍♂️ 🦹🏾‍♀️ 🦹🏾 🦹🏾‍♂️ 🤶🏾 🧑🏾‍🎄 🎅🏾 🧙🏾‍♀️ 🧙🏾 🧙🏾‍♂️ 🧝🏾‍♀️ 🧝🏾 🧝🏾‍♂️ 🧛🏾‍♀️ 🧛🏾 🧛🏾‍♂️ 🧜🏾‍♀️ 🧜🏾 🧜🏾‍♂️ 🧚🏾‍♀️ 🧚🏾 🧚🏾‍♂️ 👼🏾 🤰🏾 🤱🏾 👩🏾‍🍼 🧑🏾‍🍼 👨🏾‍🍼 🙇🏾‍♀️ 🙇🏾 🙇🏾‍♂️ 💁🏾‍♀️ 💁🏾 💁🏾‍♂️ 🙅🏾‍♀️ 🙅🏾 🙅🏾‍♂️ 🙆🏾‍♀️ 🙆🏾 🙆🏾‍♂️ 🙋🏾‍♀️ 🙋🏾 🙋🏾‍♂️ 🧏🏾‍♀️ 🧏🏾 🧏🏾‍♂️ 🤦🏾‍♀️ 🤦🏾 🤦🏾‍♂️ 🤷🏾‍♀️ 🤷🏾 🤷🏾‍♂️ 🙎🏾‍♀️ 🙎🏾 🙎🏾‍♂️ 🙍🏾‍♀️ 🙍🏾 🙍🏾‍♂️ 💇🏾‍♀️ 💇🏾 💇🏾‍♂️ 💆🏾‍♀️ 💆🏾 💆🏾‍♂️ 🧖🏾‍♀️ 🧖🏾 🧖🏾‍♂️ 💃🏾 🕺🏾 🕴🏿 👩🏾‍🦽 🧑🏾‍🦽 👨🏾‍🦽 👩🏾‍🦼 🧑🏾‍🦼 👨🏾‍🦼 🚶🏾‍♀️ 🚶🏾 🚶🏾‍♂️ 👩🏾‍🦯 🧑🏾‍🦯 👨🏾‍🦯 🧎🏾‍♀️ 🧎🏾 🧎🏾‍♂️ 🏃🏾‍♀️ 🏃🏾 🏃🏾‍♂️ 🧍🏾‍♀️ 🧍🏾 🧍🏾‍♂️ 👭🏾 🧑🏾‍🤝‍🧑🏾 👬🏾 👫🏾 🧗🏾‍♀️ 🧗🏾 🧗🏾‍♂️ 🏇🏾 🏂🏾 🏌🏾‍♀️ 🏌🏾 🏌🏾‍♂️ 🏄🏾‍♀️ 🏄🏾 🏄🏾‍♂️ 🚣🏾‍♀️ 🚣🏾 🚣🏾‍♂️ 🏊🏾‍♀️ 🏊🏾 🏊🏾‍♂️ ⛹🏾‍♀️ ⛹🏾 ⛹🏾‍♂️ 🏋🏾‍♀️ 🏋🏾 🏋🏾‍♂️ 🚴🏾‍♀️ 🚴🏾 🚴🏾‍♂️ 🚵🏾‍♀️ 🚵🏾 🚵🏾‍♂️ 🤸🏾‍♀️ 🤸🏾 🤸🏾‍♂️ 🤽🏾‍♀️ 🤽🏾 🤽🏾‍♂️ 🤾🏾‍♀️ 🤾🏾 🤾🏾‍♂️ 🤹🏾‍♀️ 🤹🏾 🤹🏾‍♂️ 🧘🏾‍♀️ 🧘🏾 🧘🏾‍♂️ 🛀🏾 🛌🏾 Black Emojis👋🏿 🤚🏿 🖐🏿 ✋🏿 🖖🏿 👌🏿 🤌🏿 🤏🏿 ✌🏿 🤞🏿 🤟🏿 🤘🏿 🤙🏿 👈🏿 👉🏿 👆🏿 🖕🏿 👇🏿 ☝🏿 👍🏿 👎🏿 ✊🏿 👊🏿 🤛🏿 🤜🏿 👏🏿 🙌🏿 👐🏿 🤲🏿 🙏🏿 ✍🏿 💅🏿 🤳🏿 💪🏿 🦵🏿 🦶🏿 👂🏿 🦻🏿 👃🏿 👶🏿 👧🏿 🧒🏿 👦🏿 👩🏿 🧑🏿 👨🏿 👩🏿‍🦱 🧑🏿‍🦱 👨🏿‍🦱 👩🏿‍🦰 🧑🏿‍🦰 👨🏿‍🦰 👱🏿‍♀️ 👱🏿 👱🏿‍♂️ 👩🏿‍🦳 🧑🏿‍🦳 👨🏿‍🦳 👩🏿‍🦲 🧑🏿‍🦲 👨🏿‍🦲 🧔🏿 👵🏿 🧓🏿 👴🏿 👲🏿 👳🏿‍♀️ 👳🏿 👳🏿‍♂️ 🧕🏿 👮🏿‍♀️ 👮🏿 👮🏿‍♂️ 👷🏿‍♀️ 👷🏿 👷🏿‍♂️ 💂🏿‍♀️ 💂🏿 💂🏿‍♂️ 🕵🏿‍♀️ 🕵🏿 🕵🏿‍♂️ 👩🏿‍⚕️ 🧑🏿‍⚕️ 👨🏿‍⚕️ 👩🏿‍🌾 🧑🏿‍🌾 👨🏿‍🌾 👩🏿‍🍳 🧑🏿‍🍳 👨🏿‍🍳 👩🏿‍🎓 🧑🏿‍🎓 👨🏿‍🎓 👩🏿‍🎤 🧑🏿‍🎤 👨🏿‍🎤 👩🏿‍🏫 🧑🏿‍🏫 👨🏿‍🏫 👩🏿‍🏭 🧑🏿‍🏭 👨🏿‍🏭 👩🏿‍💻 🧑🏿‍💻 👨🏿‍💻 👩🏿‍💼 🧑🏿‍💼 👨🏿‍💼 👩🏿‍🔧 🧑🏿‍🔧 👨🏿‍🔧 👩🏿‍🔬 🧑🏿‍🔬 👨🏿‍🔬 👩🏿‍🎨 🧑🏿‍🎨 👨🏿‍🎨 👩🏿‍🚒 🧑🏿‍🚒 👨🏿‍🚒 👩🏿‍✈️ 🧑🏿‍✈️ 👨🏿‍✈️ 👩🏿‍🚀 🧑🏿‍🚀 👨🏿‍🚀 👩🏿‍⚖️ 🧑🏿‍⚖️ 👨🏿‍⚖️ 👰🏿‍♀️ 👰🏿 👰🏿‍♂️ 🤵🏿‍♀️ 🤵🏿 🤵🏿‍♂️ 👸🏿 🤴🏿 🥷🏿 🦸🏿‍♀️ 🦸🏿 🦸🏿‍♂️ 🦹🏿‍♀️ 🦹🏿 🦹🏿‍♂️ 🤶🏿 🧑🏿‍🎄 🎅🏿 🧙🏿‍♀️ 🧙🏿 🧙🏿‍♂️ 🧝🏿‍♀️ 🧝🏿 🧝🏿‍♂️ 🧛🏿‍♀️ 🧛🏿 🧛🏿‍♂️ 🧜🏿‍♀️ 🧜🏿 🧜🏿‍♂️ 🧚🏿‍♀️ 🧚🏿 🧚🏿‍♂️ 👼🏿 🤰🏿 🤱🏿 👩🏿‍🍼 🧑🏿‍🍼 👨🏿‍🍼 🙇🏿‍♀️ 🙇🏿 🙇🏿‍♂️ 💁🏿‍♀️ 💁🏿 💁🏿‍♂️ 🙅🏿‍♀️ 🙅🏿 🙅🏿‍♂️ 🙆🏿‍♀️ 🙆🏿 🙆🏿‍♂️ 🙋🏿‍♀️ 🙋🏿 🙋🏿‍♂️ 🧏🏿‍♀️ 🧏🏿 🧏🏿‍♂️ 🤦🏿‍♀️ 🤦🏿 🤦🏿‍♂️ 🤷🏿‍♀️ 🤷🏿 🤷🏿‍♂️ 🙎🏿‍♀️ 🙎🏿 🙎🏿‍♂️ 🙍🏿‍♀️ 🙍🏿 🙍🏿‍♂️ 💇🏿‍♀️ 💇🏿 💇🏿‍♂️ 💆🏿‍♀️ 💆🏿 💆🏿‍♂️ 🧖🏿‍♀️ 🧖🏿 🧖🏿‍♂️ 💃🏿 🕺🏿 🕴🏿 👩🏿‍🦽 🧑🏿‍🦽 👨🏿‍🦽 👩🏿‍🦼 🧑🏿‍🦼 👨🏿‍🦼 🚶🏿‍♀️ 🚶🏿 🚶🏿‍♂️ 👩🏿‍🦯 🧑🏿‍🦯 👨🏿‍🦯 🧎🏿‍♀️ 🧎🏿 🧎🏿‍♂️ 🏃🏿‍♀️ 🏃🏿 🏃🏿‍♂️ 🧍🏿‍♀️ 🧍🏿 🧍🏿‍♂️ 👭🏿 🧑🏿‍🤝‍🧑🏿 👬🏿 👫🏿 🧗🏿‍♀️ 🧗🏿 🧗🏿‍♂️ 🏇🏿 🏂🏿 🏌🏿‍♀️ 🏌🏿 🏌🏿‍♂️ 🏄🏿‍♀️ 🏄🏿 🏄🏿‍♂️ 🚣🏿‍♀️ 🚣🏿 🚣🏿‍♂️ 🏊🏿‍♀️ 🏊🏿 🏊🏿‍♂️ ⛹🏿‍♀️ ⛹🏿 ⛹🏿‍♂️ 🏋🏿‍♀️ 🏋🏿 🏋🏿‍♂️ 🚴🏿‍♀️ 🚴🏿 🚴🏿‍♂️ 🚵🏿‍♀️ 🚵🏿 🚵🏿‍♂️ 🤸🏿‍♀️ 🤸🏿 🤸🏿‍♂️ 🤽🏿‍♀️ 🤽🏿 🤽🏿‍♂️ 🤾🏿‍♀️ 🤾🏿 🤾🏿‍♂️ 🤹🏿‍♀️ 🤹🏿 🤹🏿‍♂️ 🧘🏿‍♀️ 🧘🏿 🧘🏿‍♂️ 🛀🏿 🛌🏿 Animals & Nature🐶 🐱 🐭 🐹 🐰 🦊 🐻 🐼 🐻‍❄️ 🐨 🐯 🦁 🐮 🐷 🐽 🐸 🐵 🙈 🙉 🙊 🐒 🐔 🐧 🐦 🐤 🐣 🐥 🦆 🦅 🦉 🦇 🐺 🐗 🐴 🦄 🐝 🪱 🐛 🦋 🐌 🐞 🐜 🪰 🪲 🪳 🦟 🦗 🕷 🕸 🦂 🐢 🐍 🦎 🦖 🦕 🐙 🦑 🦐 🦞 🦀 🐡 🐠 🐟 🐬 🐳 🐋 🦈 🐊 🐅 🐆 🦓 🦍 🦧 🦣 🐘 🦛 🦏 🐪 🐫 🦒 🦘 🦬 🐃 🐂 🐄 🐎 🐖 🐏 🐑 🦙 🐐 🦌 🐕 🐩 🦮 🐕‍🦺 🐈 🐈‍⬛ 🪶 🐓 🦃 🦤 🦚 🦜 🦢 🦩 🕊 🐇 🦝 🦨 🦡 🦫 🦦 🦥 🐁 🐀 🐿 🦔 🐾 🐉 🐲 🌵 🎄 🌲 🌳 🌴 🪵 🌱 🌿 ☘️ 🍀 🎍 🪴 🎋 🍃 🍂 🍁 🍄 🐚 🪨 🌾 💐 🌷 🌹 🥀 🌺 🌸 🌼 🌻 🌞 🌝 🌛 🌜 🌚 🌕 🌖 🌗 🌘 🌑 🌒 🌓 🌔 🌙 🌎 🌍 🌏 🪐 💫 ⭐️ 🌟 ✨ ⚡️ ☄️ 💥 🔥 🌪 🌈 ☀️ 🌤 ⛅️ 🌥 ☁️ 🌦 🌧 ⛈ 🌩 🌨 ❄️ ☃️ ⛄️ 🌬 💨 💧 💦 ☔️ ☂️ 🌊 🌫 Food & Drink🍏 🍎 🍐 🍊 🍋 🍌 🍉 🍇 🍓 🫐 🍈 🍒 🍑 🥭 🍍 🥥 🥝 🍅 🍆 🥑 🥦 🥬 🥒 🌶 🫑 🌽 🥕 🫒 🧄 🧅 🥔 🍠 🥐 🥯 🍞 🥖 🥨 🧀 🥚 🍳 🧈 🥞 🧇 🥓 🥩 🍗 🍖 🦴 🌭 🍔 🍟 🍕 🫓 🥪 🥙 🧆 🌮 🌯 🫔 🥗 🥘 🫕 🥫 🍝 🍜 🍲 🍛 🍣 🍱 🥟 🦪 🍤 🍙 🍚 🍘 🍥 🥠 🥮 🍢 🍡 🍧 🍨 🍦 🥧 🧁 🍰 🎂 🍮 🍭 🍬 🍫 🍿 🍩 🍪 🌰 🥜 🍯 🥛 🍼 🫖 ☕️ 🍵 🧃 🥤 🧋 🍶 🍺 🍻 🥂 🍷 🥃 🍸 🍹 🧉 🍾 🧊 🥄 🍴 🍽 🥣 🥡 🥢 🧂 Activity and Sports⚽️ 🏀 🏈 ⚾️ 🥎 🎾 🏐 🏉 🥏 🎱 🪀 🏓 🏸 🏒 🏑 🥍 🏏 🪃 🥅 ⛳️ 🪁 🏹 🎣 🤿 🥊 🥋 🎽 🛹 🛼 🛷 ⛸ 🥌 🎿 ⛷ 🏂 🪂 🏋️‍♀️ 🏋️ 🏋️‍♂️ 🤼‍♀️ 🤼 🤼‍♂️ 🤸‍♀️ 🤸 🤸‍♂️ ⛹️‍♀️ ⛹️ ⛹️‍♂️ 🤺 🤾‍♀️ 🤾 🤾‍♂️ 🏌️‍♀️ 🏌️ 🏌️‍♂️ 🏇 🧘‍♀️ 🧘 🧘‍♂️ 🏄‍♀️ 🏄 🏄‍♂️ 🏊‍♀️ 🏊 🏊‍♂️ 🤽‍♀️ 🤽 🤽‍♂️ 🚣‍♀️ 🚣 🚣‍♂️ 🧗‍♀️ 🧗 🧗‍♂️ 🚵‍♀️ 🚵 🚵‍♂️ 🚴‍♀️ 🚴 🚴‍♂️ 🏆 🥇 🥈 🥉 🏅 🎖 🏵 🎗 🎫 🎟 🎪 🤹 🤹‍♂️ 🤹‍♀️ 🎭 🩰 🎨 🎬 🎤 🎧 🎼 🎹 🥁 🪘 🎷 🎺 🪗 🎸 🪕 🎻 🎲 ♟ 🎯 🎳 🎮 🎰 🧩 Travel & Places🚗 🚕 🚙 🚌 🚎 🏎 🚓 🚑 🚒 🚐 🛻 🚚 🚛 🚜 🦯 🦽 🦼 🛴 🚲 🛵 🏍 🛺 🚨 🚔 🚍 🚘 🚖 🚡 🚠 🚟 🚃 🚋 🚞 🚝 🚄 🚅 🚈 🚂 🚆 🚇 🚊 🚉 ✈️ 🛫 🛬 🛩 💺 🛰 🚀 🛸 🚁 🛶 ⛵️ 🚤 🛥 🛳 ⛴ 🚢 ⚓️ 🪝 ⛽️ 🚧 🚦 🚥 🚏 🗺 🗿 🗽 🗼 🏰 🏯 🏟 🎡 🎢 🎠 ⛲️ ⛱ 🏖 🏝 🏜 🌋 ⛰ 🏔 🗻 🏕 ⛺️ 🛖 🏠 🏡 🏘 🏚 🏗 🏭 🏢 🏬 🏣 🏤 🏥 🏦 🏨 🏪 🏫 🏩 💒 🏛 ⛪️ 🕌 🕍 🛕 🕋 ⛩ 🛤 🛣 🗾 🎑 🏞 🌅 🌄 🌠 🎇 🎆 🌇 🌆 🏙 🌃 🌌 🌉 🌁 Objects⌚️ 📱 📲 💻 ⌨️ 🖥 🖨 🖱 🖲 🕹 🗜 💽 💾 💿 📀 📼 📷 📸 📹 🎥 📽 🎞 📞 ☎️ 📟 📠 📺 📻 🎙 🎚 🎛 🧭 ⏱ ⏲ ⏰ 🕰 ⌛️ ⏳ 📡 🔋 🔌 💡 🔦 🕯 🪔 🧯 🛢 💸 💵 💴 💶 💷 🪙 💰 💳 💎 ⚖️ 🪜 🧰 🪛 🔧 🔨 ⚒ 🛠 ⛏ 🪚 🔩 ⚙️ 🪤 🧱 ⛓ 🧲 🔫 💣 🧨 🪓 🔪 🗡 ⚔️ 🛡 🚬 ⚰️ 🪦 ⚱️ 🏺 🔮 📿 🧿 💈 ⚗️ 🔭 🔬 🕳 🩹 🩺 💊 💉 🩸 🧬 🦠 🧫 🧪 🌡 🧹 🪠 🧺 🧻 🚽 🚰 🚿 🛁 🛀 🧼 🪥 🪒 🧽 🪣 🧴 🛎 🔑 🗝 🚪 🪑 🛋 🛏 🛌 🧸 🪆 🖼 🪞 🪟 🛍 🛒 🎁 🎈 🎏 🎀 🪄 🪅 🎊 🎉 🎎 🏮 🎐 🧧 ✉️ 📩 📨 📧 💌 📥 📤 📦 🏷 🪧 📪 📫 📬 📭 📮 📯 📜 📃 📄 📑 🧾 📊 📈 📉 🗒 🗓 📆 📅 🗑 📇 🗃 🗳 🗄 📋 📁 📂 🗂 🗞 📰 📓 📔 📒 📕 📗 📘 📙 📚 📖 🔖 🧷 🔗 📎 🖇 📐 📏 🧮 📌 📍 ✂️ 🖊 🖋 ✒️ 🖌 🖍 📝 ✏️ 🔍 🔎 🔏 🔐 🔒 🔓 Symbols❤️ 🧡 💛 💚 💙 💜 🖤 🤍 🤎 💔 ❣️ 💕 💞 💓 💗 💖 💘 💝 💟 ☮️ ✝️ ☪️ 🕉 ☸️ ✡️ 🔯 🕎 ☯️ ☦️ 🛐 ⛎ ♈️ ♉️ ♊️ ♋️ ♌️ ♍️ ♎️ ♏️ ♐️ ♑️ ♒️ ♓️ 🆔 ⚛️ 🉑 ☢️ ☣️ 📴 📳 🈶 🈚️ 🈸 🈺 🈷️ ✴️ 🆚 💮 🉐 ㊙️ ㊗️ 🈴 🈵 🈹 🈲 🅰️ 🅱️ 🆎 🆑 🅾️ 🆘 ❌ ⭕️ 🛑 ⛔️ 📛 🚫 💯 💢 ♨️ 🚷 🚯 🚳 🚱 🔞 📵 🚭 ❗️ ❕ ❓ ❔ ‼️ ⁉️ 🔅 🔆 〽️ ⚠️ 🚸 🔱 ⚜️ 🔰 ♻️ ✅ 🈯️ 💹 ❇️ ✳️ ❎ 🌐 💠 Ⓜ️ 🌀 💤 🏧 🚾 ♿️ 🅿️ 🛗 🈳 🈂️ 🛂 🛃 🛄 🛅 🚹 🚺 🚼 ⚧ 🚻 🚮 🎦 📶 🈁 🔣 ℹ️ 🔤 🔡 🔠 🆖 🆗 🆙 🆒 🆕 🆓 0️⃣ 1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟 🔢 #️⃣ *️⃣ ⏏️ ▶️ ⏸ ⏯ ⏹ ⏺ ⏭ ⏮ ⏩ ⏪ ⏫ ⏬ ◀️ 🔼 🔽 ➡️ ⬅️ ⬆️ ⬇️ ↗️ ↘️ ↙️ ↖️ ↕️ ↔️ ↪️ ↩️ ⤴️ ⤵️ 🔀 🔁 🔂 🔄 🔃 🎵 🎶 ➕ ➖ ➗ ✖️ ♾ 💲 💱 ™️ ©️ ®️ 〰️ ➰ ➿ 🔚 🔙 🔛 🔝 🔜 ✔️ ☑️ 🔘 🔴 🟠 🟡 🟢 🔵 🟣 ⚫️ ⚪️ 🟤 🔺 🔻 🔸 🔹 🔶 🔷 🔳 🔲 -️ ▫️ ◾️ ◽️ ◼️ ◻️ 🟥 🟧 🟨 🟩 🟦 🟪 ⬛️ ⬜️ 🟫 🔈 🔇 🔉 🔊 🔔 🔕 📣 📢 👁‍🗨 💬 💭 🗯 ♠️ ♣️ ♥️ ♦️ 🃏 🎴 🀄️ 🕐 🕑 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 🕛 🕜 🕝 🕞 🕟 🕠 🕡 🕢 🕣 🕤 🕥 🕦 🕧 Non-Emoji Symbols More Unicode symbols, Hieroglpyhs and Pictographs to copy and paste.✢ ✣ ✤ ✥ ✦ ✧ ★ ☆ ✯ ✡︎ ✩ ✪ ✫ ✬ ✭ ✮ ✶ ✷ ✵ ✸ ✹ → ⇒ ⟹ ⇨ ⇾ ➾ ⇢ ☛ ☞ ➔ ➜ ➙ ➛ ➝ ➞ ♠︎ ♣︎ ♥︎ ♦︎ ♤ ♧ ♡ ♢ ♚ ♛ ♜ ♝ ♞ ♟ ♔ ♕ ♖ ♗ ♘ ♙ ⚀ ⚁ ⚂ ⚃ ⚄ ⚅ 🂠 ⚈ ⚉ ⚆ ⚇ 𓀀 𓀁 𓀂 𓀃 𓀄 𓀅 𓀆 𓀇 𓀈 𓀉 𓀊 𓀋 𓀌 𓀍 𓀎 𓀏 𓀐 𓀑 𓀒 𓀓 𓀔 𓀕 𓀖 𓀗 𓀘 𓀙 𓀚 𓀛 𓀜 𓀝 Flags Note: Windows has limited flag emoji support.🏳️ 🏴 🏁 🚩 🏳️‍🌈 🏳️‍⚧️ 🏴‍☠️ 🇦🇫 🇦🇽 🇦🇱 🇩🇿 🇦🇸 🇦🇩 🇦🇴 🇦🇮 🇦🇶 🇦🇬 🇦🇷 🇦🇲 🇦🇼 🇦🇺 🇦🇹 🇦🇿 🇧🇸 🇧🇭 🇧🇩 🇧🇧 🇧🇾 🇧🇪 🇧🇿 🇧🇯 🇧🇲 🇧🇹 🇧🇴 🇧🇦 🇧🇼 🇧🇷 🇮🇴 🇻🇬 🇧🇳 🇧🇬 🇧🇫 🇧🇮 🇰🇭 🇨🇲 🇨🇦 🇮🇨 🇨🇻 🇧🇶 🇰🇾 🇨🇫 🇹🇩 🇨🇱 🇨🇳 🇨🇽 🇨🇨 🇨🇴 🇰🇲 🇨🇬 🇨🇩 🇨🇰 🇨🇷 🇨🇮 🇭🇷 🇨🇺 🇨🇼 🇨🇾 🇨🇿 🇩🇰 🇩🇯 🇩🇲 🇩🇴 🇪🇨 🇪🇬 🇸🇻 🇬🇶 🇪🇷 🇪🇪 🇪🇹 🇪🇺 🇫🇰 🇫🇴 🇫🇯 🇫🇮 🇫🇷 🇬🇫 🇵🇫 🇹🇫 🇬🇦 🇬🇲 🇬🇪 🇩🇪 🇬🇭 🇬🇮 🇬🇷 🇬🇱 🇬🇩 🇬🇵 🇬🇺 🇬🇹 🇬🇬 🇬🇳 🇬🇼 🇬🇾 🇭🇹 🇭🇳 🇭🇰 🇭🇺 🇮🇸 🇮🇳 🇮🇩 🇮🇷 🇮🇶 🇮🇪 🇮🇲 🇮🇱 🇮🇹 🇯🇲 🇯🇵 🎌 🇯🇪 🇯🇴 🇰🇿 🇰🇪 🇰🇮 🇽🇰 🇰🇼 🇰🇬 🇱🇦 🇱🇻 🇱🇧 🇱🇸 🇱🇷 🇱🇾 🇱🇮 🇱🇹 🇱🇺 🇲🇴 🇲🇰 🇲🇬 🇲🇼 🇲🇾 🇲🇻 🇲🇱 🇲🇹 🇲🇭 🇲🇶 🇲🇷 🇲🇺 🇾🇹 🇲🇽 🇫🇲 🇲🇩 🇲🇨 🇲🇳 🇲🇪 🇲🇸 🇲🇦 🇲🇿 🇲🇲 🇳🇦 🇳🇷 🇳🇵 🇳🇱 🇳🇨 🇳🇿 🇳🇮 🇳🇪 🇳🇬 🇳🇺 🇳🇫 🇰🇵 🇲🇵 🇳🇴 🇴🇲 🇵🇰 🇵🇼 🇵🇸 🇵🇦 🇵🇬 🇵🇾 🇵🇪 🇵🇭 🇵🇳 🇵🇱 🇵🇹 🇵🇷 🇶🇦 🇷🇪 🇷🇴 🇷🇺 🇷🇼 🇼🇸 🇸🇲 🇸🇦 🇸🇳 🇷🇸 🇸🇨 🇸🇱 🇸🇬 🇸🇽 🇸🇰 🇸🇮 🇬🇸 🇸🇧 🇸🇴 🇿🇦 🇰🇷 🇸🇸 🇪🇸 🇱🇰 🇧🇱 🇸🇭 🇰🇳 🇱🇨 🇵🇲 🇻🇨 🇸🇩 🇸🇷 🇸🇿 🇸🇪 🇨🇭 🇸🇾 🇹🇼 🇹🇯 🇹🇿 🇹🇭 🇹🇱 🇹🇬 🇹🇰 🇹🇴 🇹🇹 🇹🇳 🇹🇷 🇹🇲 🇹🇨 🇹🇻 🇻🇮 🇺🇬 🇺🇦 🇦🇪 🇬🇧 🏴󠁧󠁢󠁥󠁮󠁧󠁿 🏴󠁧󠁢󠁳󠁣󠁴󠁿 🏴󠁧󠁢󠁷󠁬󠁳󠁿 🇺🇳 🇺🇸 🇺🇾 🇺🇿 🇻🇺 🇻🇦 🇻🇪 🇻🇳 🇼🇫 🇪🇭 🇾🇪 🇿🇲 🇿🇼😃💁 People - 🐻🌻 Animals - 🍔🍹 Food - 🎷⚽️ Activities - 🚘🌇 Travel - 💡🎉 Objects - 💖🔣 Symbols - 🎌🏳️‍🌈 Flags New Emojis Emojis from Emoji 13.0: Added in 2020.🥲 🥸 🤌 🤌🏻 🤌🏼 🤌🏽 🤌🏾 🤌🏿 🫀 🫁 🥷 🤵‍♀️ 🤵🏻‍♀️ 🤵🏼‍♀️ 🤵🏽‍♀️ 🤵🏾‍♀️ 🤵🏿‍♀️ 🤵‍♂️ 🤵🏻‍♂️ 🤵🏼‍♂️ 🤵🏽‍♂️ 🤵🏾‍♂️ 🤵🏿‍♂️ 👰‍♀️ 👰🏻‍♀️ 👰🏼‍♀️ 👰🏽‍♀️ 👰🏾‍♀️ 👰🏿‍♀️ 👰‍♂️ 👰🏻‍♂️ 👰🏼‍♂️ 👰🏽‍♂️ 👰🏾‍♂️ 👰🏿‍♂️ 👩‍🍼 👩🏻‍🍼 👩🏼‍🍼 👩🏽‍🍼 👩🏾‍🍼 👩🏿‍🍼 🧑‍🍼 🧑🏻‍🍼 🧑🏼‍🍼 🧑🏽‍🍼 🧑🏾‍🍼 🧑🏿‍🍼 👨‍🍼 👨🏻‍🍼 👨🏼‍🍼 👨🏽‍🍼 👨🏾‍🍼 👨🏿‍🍼 🧑‍🎄 🧑🏻‍🎄 🧑🏼‍🎄 🧑🏽‍🎄 🧑🏾‍🎄 🧑🏿‍🎄 🫂 🐈‍⬛ 🦬 🦣 🦫 🐻‍❄️ 🦤 🪶 🦭 🪲 🪳 🪰 🪱 🪴 🫐 🫒 🫑 🫓 🫔 🫕 🫖 🧋 🪨 🪵 🛖 🛻 🛼 🪄 🪅 🪆 🪡 🪢 🩴 🪖 🪗 🪘 🪙 🪃 🪚 🪛 🪝 🪜 🛗 🪞 🪟 🪠 🪤 🪣 🪥 🪦 🪧 🏳️‍⚧️ Emojis from Emoji 13.1: Added in 2021.😮‍💨 😵‍💫 😶‍🌫️ ❤️‍🔥 ❤️‍🩹 🧔‍♀️ 🧔🏻‍♀️ 🧔🏼‍♀️ 🧔🏽‍♀️ 🧔🏾‍♀️ 🧔🏿‍♀️ 🧔‍♂️ 🧔🏻‍♂️ 🧔🏼‍♂️ 🧔🏽‍♂️ 🧔🏾‍♂️ 🧔🏿‍♂️ 💑🏻 💑🏼 💑🏽 💑🏾 💑🏿 💏🏻 💏🏼 💏🏽 💏🏾 💏🏿 👨🏻‍❤️‍👨🏻 👨🏻‍❤️‍👨🏼 👨🏻‍❤️‍👨🏽 👨🏻‍❤️‍👨🏾 👨🏻‍❤️‍👨🏿 👨🏼‍❤️‍👨🏻 👨🏼‍❤️‍👨🏼 👨🏼‍❤️‍👨🏽 👨🏼‍❤️‍👨🏾 👨🏼‍❤️‍👨🏿 👨🏽‍❤️‍👨🏻 👨🏽‍❤️‍👨🏼 👨🏽‍❤️‍👨🏽 👨🏽‍❤️‍👨🏾 👨🏽‍❤️‍👨🏿 👨🏾‍❤️‍👨🏻 👨🏾‍❤️‍👨🏼 👨🏾‍❤️‍👨🏽 👨🏾‍❤️‍👨🏾 👨🏾‍❤️‍👨🏿 👨🏿‍❤️‍👨🏻 👨🏿‍❤️‍👨🏼 👨🏿‍❤️‍👨🏽 👨🏿‍❤️‍👨🏾 👨🏿‍❤️‍👨🏿 👩🏻‍❤️‍👨🏻 👩🏻‍❤️‍👨🏼 👩🏻‍❤️‍👨🏽 👩🏻‍❤️‍👨🏾 👩🏻‍❤️‍👨🏿 👩🏻‍❤️‍👩🏻 👩🏻‍❤️‍👩🏼 👩🏻‍❤️‍👩🏽 👩🏻‍❤️‍👩🏾 👩🏻‍❤️‍👩🏿 👩🏼‍❤️‍👨🏻 👩🏼‍❤️‍👨🏼 👩🏼‍❤️‍👨🏽 👩🏼‍❤️‍👨🏾 👩🏼‍❤️‍👨🏿 👩🏼‍❤️‍👩🏻 👩🏼‍❤️‍👩🏼 👩🏼‍❤️‍👩🏽 👩🏼‍❤️‍👩🏾 👩🏼‍❤️‍👩🏿 👩🏽‍❤️‍👨🏻 👩🏽‍❤️‍👨🏼 👩🏽‍❤️‍👨🏽 👩🏽‍❤️‍👨🏾 👩🏽‍❤️‍👨🏿 👩🏽‍❤️‍👩🏻 👩🏽‍❤️‍👩🏼 👩🏽‍❤️‍👩🏽 👩🏽‍❤️‍👩🏾 👩🏽‍❤️‍👩🏿 👩🏾‍❤️‍👨🏻 👩🏾‍❤️‍👨🏼 👩🏾‍❤️‍👨🏽 👩🏾‍❤️‍👨🏾 👩🏾‍❤️‍👨🏿 👩🏾‍❤️‍👩🏻 👩🏾‍❤️‍👩🏼 👩🏾‍❤️‍👩🏽 👩🏾‍❤️‍👩🏾 👩🏾‍❤️‍👩🏿 👩🏿‍❤️‍👨🏻 👩🏿‍❤️‍👨🏼 👩🏿‍❤️‍👨🏽 👩🏿‍❤️‍👨🏾 👩🏿‍❤️‍👨🏿 👩🏿‍❤️‍👩🏻 👩🏿‍❤️‍👩🏼 👩🏿‍❤️‍👩🏽 👩🏿‍❤️‍👩🏾 👩🏿‍❤️‍👩🏿 🧑🏻‍❤️‍🧑🏼 🧑🏻‍❤️‍🧑🏽 🧑🏻‍❤️‍🧑🏾 🧑🏻‍❤️‍🧑🏿 🧑🏼‍❤️‍🧑🏻 🧑🏼‍❤️‍🧑🏽 🧑🏼‍❤️‍🧑🏾 🧑🏼‍❤️‍🧑🏿 🧑🏽‍❤️‍🧑🏻 🧑🏽‍❤️‍🧑🏼 🧑🏽‍❤️‍🧑🏾 🧑🏽‍❤️‍🧑🏿 🧑🏾‍❤️‍🧑🏻 🧑🏾‍❤️‍🧑🏼 🧑🏾‍❤️‍🧑🏽 🧑🏾‍❤️‍🧑🏿 🧑🏿‍❤️‍🧑🏻 🧑🏿‍❤️‍🧑🏼 🧑🏿‍❤️‍🧑🏽 🧑🏿‍❤️‍🧑🏾 👨🏻‍❤️‍💋‍👨🏻 👨🏻‍❤️‍💋‍👨🏼 👨🏻‍❤️‍💋‍👨🏽 👨🏻‍❤️‍💋‍👨🏾 👨🏻‍❤️‍💋‍👨🏿 👨🏼‍❤️‍💋‍👨🏻 👨🏼‍❤️‍💋‍👨🏼 👨🏼‍❤️‍💋‍👨🏽 👨🏼‍❤️‍💋‍👨🏾 👨🏼‍❤️‍💋‍👨🏿 👨🏽‍❤️‍💋‍👨🏻 👨🏽‍❤️‍💋‍👨🏼 👨🏽‍❤️‍💋‍👨🏽 👨🏽‍❤️‍💋‍👨🏾 👨🏽‍❤️‍💋‍👨🏿 👨🏾‍❤️‍💋‍👨🏻 👨🏾‍❤️‍💋‍👨🏼 👨🏾‍❤️‍💋‍👨🏽 👨🏾‍❤️‍💋‍👨🏾 👨🏾‍❤️‍💋‍👨🏿 👨🏿‍❤️‍💋‍👨🏻 👨🏿‍❤️‍💋‍👨🏼 👨🏿‍❤️‍💋‍👨🏽 👨🏿‍❤️‍💋‍👨🏾 👨🏿‍❤️‍💋‍👨🏿 👩🏻‍❤️‍💋‍👨🏻 👩🏻‍❤️‍💋‍👨🏼 👩🏻‍❤️‍💋‍👨🏽 👩🏻‍❤️‍💋‍👨🏾 👩🏻‍❤️‍💋‍👨🏿 👩🏻‍❤️‍💋‍👩🏻 👩🏻‍❤️‍💋‍👩🏼 👩🏻‍❤️‍💋‍👩🏽 👩🏻‍❤️‍💋‍👩🏾 👩🏻‍❤️‍💋‍👩🏿 👩🏼‍❤️‍💋‍👨🏻 👩🏼‍❤️‍💋‍👨🏼 👩🏼‍❤️‍💋‍👨🏽 👩🏼‍❤️‍💋‍👨🏾 👩🏼‍❤️‍💋‍👨🏿 👩🏼‍❤️‍💋‍👩🏻 👩🏼‍❤️‍💋‍👩🏼 👩🏼‍❤️‍💋‍👩🏽 👩🏼‍❤️‍💋‍👩🏾 👩🏼‍❤️‍💋‍👩🏿 👩🏽‍❤️‍💋‍👨🏻 👩🏽‍❤️‍💋‍👨🏼 👩🏽‍❤️‍💋‍👨🏽 👩🏽‍❤️‍💋‍👨🏾 👩🏽‍❤️‍💋‍👨🏿 👩🏽‍❤️‍💋‍👩🏻 👩🏽‍❤️‍💋‍👩🏼 👩🏽‍❤️‍💋‍👩🏽 👩🏽‍❤️‍💋‍👩🏾 👩🏽‍❤️‍💋‍👩🏿 👩🏾‍❤️‍💋‍👨🏻 👩🏾‍❤️‍💋‍👨🏼 👩🏾‍❤️‍💋‍👨🏽 👩🏾‍❤️‍💋‍👨🏾 👩🏾‍❤️‍💋‍👨🏿 👩🏾‍❤️‍💋‍👩🏻 👩🏾‍❤️‍💋‍👩🏼 👩🏾‍❤️‍💋‍👩🏽 👩🏾‍❤️‍💋‍👩🏾 👩🏾‍❤️‍💋‍👩🏿 👩🏿‍❤️‍💋‍👨🏻 👩🏿‍❤️‍💋‍👨🏼 👩🏿‍❤️‍💋‍👨🏽 👩🏿‍❤️‍💋‍👨🏾 👩🏿‍❤️‍💋‍👨🏿 👩🏿‍❤️‍💋‍👩🏻 👩🏿‍❤️‍💋‍👩🏼 👩🏿‍❤️‍💋‍👩🏽 👩🏿‍❤️‍💋‍👩🏾 👩🏿‍❤️‍💋‍👩🏿 🧑🏻‍❤️‍💋‍🧑🏼 🧑🏻‍❤️‍💋‍🧑🏽 🧑🏻‍❤️‍💋‍🧑🏾 🧑🏻‍❤️‍💋‍🧑🏿 🧑🏼‍❤️‍💋‍🧑🏻 🧑🏼‍❤️‍💋‍🧑🏽 🧑🏼‍❤️‍💋‍🧑🏾 🧑🏼‍❤️‍💋‍🧑🏿 🧑🏽‍❤️‍💋‍🧑🏻 🧑🏽‍❤️‍💋‍🧑🏼 🧑🏽‍❤️‍💋‍🧑🏾 🧑🏽‍❤️‍💋‍🧑🏿 🧑🏾‍❤️‍💋‍🧑🏻 🧑🏾‍❤️‍💋‍🧑🏼 🧑🏾‍❤️‍💋‍🧑🏽 🧑🏾‍❤️‍💋‍🧑🏿 🧑🏿‍❤️‍💋‍🧑🏻 🧑🏿‍❤️‍💋‍🧑🏼 🧑🏿‍❤️‍💋‍🧑🏽 🧑🏿‍❤️‍💋‍🧑🏾
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Python Snippets Python Snippets Calculates the date of n days from the given date. Use datetime.timedelta and the + operator to calculate the new datetime.datetime value after adding n days to d. Omit the second argument, d, to use a default value of datetime.today(). from datetime import datetime, timedelta def add_days(n, d = datetime.today()): return d + timedelta(n) from datetime import date add_days(5, date(2020, 10, 25)) # date(2020, 10, 30) add_days(-5, date(2020, 10, 25)) # date(2020, 10, 20) Checks if all elements in a list are equal. Use set() to eliminate duplicate elements and then use len() to check if length is 1. def all_equal(lst): return len(set(lst)) == 1 all_equal([1, 2, 3, 4, 5, 6]) # False all_equal([1, 1, 1, 1]) # True Checks if all the values in a list are unique. Use set() on the given list to keep only unique occurrences. Use len() to compare the length of the unique values to the original list. def all_unique(lst): return len(lst) == len(set(lst)) x = [1, 2, 3, 4, 5, 6] y = [1, 2, 2, 3, 4, 5] all_unique(x) # True all_unique(y) # False Generates a list of numbers in the arithmetic progression starting with the given positive integer and up to the specified limit. Use range() and list() with the appropriate start, step and end values. def arithmetic_progression(n, lim): return list(range(n, lim + 1, n)) arithmetic_progression(5, 25) # [5, 10, 15, 20, 25] Calculates the average of two or more numbers. Use sum() to sum all of the args provided, divide by len(). def average(*args): return sum(args, 0.0) / len(args) average(*[1, 2, 3]) # 2.0 average(1, 2, 3) # 2.0 Calculates the average of a list, after mapping each element to a value using the provided function. Use map() to map each element to the value returned by fn. Use sum() to sum all of the mapped values, divide by len(lst). Omit the last argument, fn, to use the default identity function. def average_by(lst, fn = lambda x: x): return sum(map(fn, lst), 0.0) / len(lst) average_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda x: x['n']) # 5.0 Splits values into two groups, based on the result of the given filter list. Use a list comprehension and zip() to add elements to groups, based on filter. If filter has a truthy value for any element, add it to the first group, otherwise add it to the second group. def bifurcate(lst, filter): return [ [x for x, flag in zip(lst, filter) if flag], [x for x, flag in zip(lst, filter) if not flag] ] bifurcate(['beep', 'boop', 'foo', 'bar'], [True, True, False, True]) # [ ['beep', 'boop', 'bar'], ['foo'] ] Splits values into two groups, based on the result of the given filtering function. Use a list comprehension to add elements to groups, based on the value returned by fn for each element. If fn returns a truthy value for any element, add it to the first group, otherwise add it to the second group. def bifurcate_by(lst, fn): return [ [x for x in lst if fn(x)], [x for x in lst if not fn(x)] ] bifurcate_by(['beep', 'boop', 'foo', 'bar'], lambda x: x[0] == 'b') # [ ['beep', 'boop', 'bar'], ['foo'] ] Calculates the number of ways to choose k items from n items without repetition and without order. Use math.comb() to calculate the binomial coefficient. from math import comb def binomial_coefficient(n, k): return comb(n, k) binomial_coefficient(8, 2) # 28 Returns the length of a string in bytes. Use str.encode('utf-8') to encode the given string and return its length. def byte_size(s): return len(s.encode('utf-8')) byte_size('😀') # 4 byte_size('Hello World') # 11 Converts a string to camelcase. Use re.sub() to replace any - or _ with a space, using the regexp r"(_|-)+". Use str.title() to capitalize the first letter of each word and convert the rest to lowercase. Finally, use str.replace() to remove spaces between words. from re import sub def camel(s): s = sub(r"(_|-)+", " ", s).title().replace(" ", "") return ''.join([s[0].lower(), s[1:]]) camel('some_database_field_name') # 'someDatabaseFieldName' camel('Some label that needs to be camelized') # 'someLabelThatNeedsToBeCamelized' camel('some-javascript-property') # 'someJavascriptProperty' camel('some-mixed_string with spaces_underscores-and-hyphens') # 'someMixedStringWithSpacesUnderscoresAndHyphens' Capitalizes the first letter of a string. Use list slicing and str.upper() to capitalize the first letter of the string. Use str.join() to combine the capitalized first letter with the rest of the characters. Omit the lower_rest parameter to keep the rest of the string intact, or set it to True to convert to lowercase. def capitalize(s, lower_rest = False): return ''.join([s[:1].upper(), (s[1:].lower() if lower_rest else s[1:])]) capitalize('fooBar') # 'FooBar' capitalize('fooBar', True) # 'Foobar' Capitalizes the first letter of every word in a string. Use str.title() to capitalize the first letter of every word in the string. def capitalize_every_word(s): return s.title() capitalize_every_word('hello world!') # 'Hello World!' Casts the provided value as a list if it's not one. Use isinstance() to check if the given value is enumerable. Return it by using list() or encapsulated in a list accordingly. def cast_list(val): return list(val) if isinstance(val, (tuple, list, set, dict)) else [val] cast_list('foo') # ['foo'] cast_list([1]) # [1] cast_list(('foo', 'bar')) # ['foo', 'bar'] unlisted: true Converts Celsius to Fahrenheit. Follow the conversion formula F = 1.8 * C + 32. def celsius_to_fahrenheit(degrees): return ((degrees * 1.8) + 32) celsius_to_fahrenheit(180) # 356.0 Creates a function that will invoke a predicate function for the specified property on a given object. Return a lambda function that takes an object and applies the predicate function, fn to the specified property. def check_prop(fn, prop): return lambda obj: fn(obj[prop]) check_age = check_prop(lambda x: x >= 18, 'age') user = {'name': 'Mark', 'age': 18} check_age(user) # True Chunks a list into smaller lists of a specified size. Use list() and range() to create a list of the desired size. Use map() on the list and fill it with splices of the given list. Finally, return the created list. from math import ceil def chunk(lst, size): return list( map(lambda x: lst[x * size:x * size + size], list(range(ceil(len(lst) / size))))) chunk([1, 2, 3, 4, 5], 2) # [[1, 2], [3, 4], [5]] Chunks a list into n smaller lists. Use math.ceil() and len() to get the size of each chunk. Use list() and range() to create a new list of size n. Use map() to map each element of the new list to a chunk the length of size. If the original list can't be split evenly, the final chunk will contain the remaining elements. from math import ceil def chunk_into_n(lst, n): size = ceil(len(lst) / n) return list( map(lambda x: lst[x * size:x * size + size], list(range(n))) ) chunk_into_n([1, 2, 3, 4, 5, 6, 7], 4) # [[1, 2], [3, 4], [5, 6], [7]] Clamps num within the inclusive range specified by the boundary values. If num falls within the range ( a, b), return num. Otherwise, return the nearest number in the range. def clamp_number(num, a, b): return max(min(num, max(a, b)), min(a, b)) clamp_number(2, 3, 5) # 3 clamp_number(1, -1, -5) # -1 Inverts a dictionary with non-unique hashable values. Create a collections.defaultdict with list as the default value for each key. Use dictionary.items() in combination with a loop to map the values of the dictionary to keys using dict.append(). Use dict() to convert the collections.defaultdict to a regular dictionary. from collections import defaultdict def collect_dictionary(obj): inv_obj = defaultdict(list) for key, value in obj.items(): inv_obj[value].append(key) return dict(inv_obj) ages = { 'Peter': 10, 'Isabel': 10, 'Anna': 9, } collect_dictionary(ages) # { 10: ['Peter', 'Isabel'], 9: ['Anna'] } Combines two or more dictionaries, creating a list of values for each key. Create a new collections.defaultdict with list as the default value for each key and loop over dicts. Use dict.append() to map the values of the dictionary to keys. Use dict() to convert the collections.defaultdict to a regular dictionary. from collections import defaultdict def combine_values(*dicts): res = defaultdict(list) for d in dicts: for key in d: res[key].append(d[key]) return dict(res) d1 = {'a': 1, 'b': 'foo', 'c': 400} d2 = {'a': 3, 'b': 200, 'd': 400} combine_values(d1, d2) # {'a': [1, 3], 'b': ['foo', 200], 'c': [400], 'd': [400]} Removes falsy values from a list. Use filter() to filter out falsy values ( False, None, 0, and ""). def compact(lst): return list(filter(None, lst)) compact([0, 1, False, 2, '', 3, 'a', 's', 34]) # [ 1, 2, 3, 'a', 's', 34 ] Performs right-to-left function composition. Use functools.reduce() to perform right-to-left function composition. The last (rightmost) function can accept one or more arguments; the remaining functions must be unary. from functools import reduce def compose(*fns): return reduce(lambda f, g: lambda *args: f(g(*args)), fns) add5 = lambda x: x + 5 multiply = lambda x, y: x * y multiply_and_add_5 = compose(add5, multiply) multiply_and_add_5(5, 2) # 15 Performs left-to-right function composition. Use functools.reduce() to perform left-to-right function composition. The first (leftmost) function can accept one or more arguments; the remaining functions must be unary. from functools import reduce def compose_right(*fns): return reduce(lambda f, g: lambda *args: g(f(*args)), fns) add = lambda x, y: x + y square = lambda x: x * x add_and_square = compose_right(add, square) add_and_square(1, 2) # 9 Groups the elements of a list based on the given function and returns the count of elements in each group. Use collections.defaultdict to initialize a dictionary. Use map() to map the values of the given list using the given function. Iterate over the map and increase the element count each time it occurs. from collections import defaultdict def count_by(lst, fn = lambda x: x): count = defaultdict(int) for val in map(fn, lst): count[val] += 1 return dict(count) from math import floor count_by([6.1, 4.2, 6.3], floor) # {6: 2, 4: 1} count_by(['one', 'two', 'three'], len) # {3: 2, 5: 1} Counts the occurrences of a value in a list. Use list.count() to count the number of occurrences of val in lst. def count_occurrences(lst, val): return lst.count(val) count_occurrences([1, 1, 2, 1, 2, 3], 1) # 3 Creates a list of partial sums. Use itertools.accumulate() to create the accumulated sum for each element. Use list() to convert the result into a list. from itertools import accumulate def cumsum(lst): return list(accumulate(lst)) cumsum(range(0, 15, 3)) # [0, 3, 9, 18, 30] Curries a function. Use functools.partial() to return a new partial object which behaves like fn with the given arguments, args, partially applied. from functools import partial def curry(fn, *args): return partial(fn, *args) add = lambda x, y: x + y add10 = curry(add, 10) add10(20) # 30 Creates a list of dates between start (inclusive) and end (not inclusive). Use datetime.timedelta.days to get the days between start and end. Use int() to convert the result to an integer and range() to iterate over each day. Use a list comprehension and datetime.timedelta() to create a list of datetime.date objects. from datetime import timedelta, date def daterange(start, end): return [start + timedelta(n) for n in range(int((end - start).days))] from datetime import date daterange(date(2020, 10, 1), date(2020, 10, 5)) # [date(2020, 10, 1), date(2020, 10, 2), date(2020, 10, 3), date(2020, 10, 4)] Calculates the date of n days ago from today. Use datetime.date.today() to get the current day. Use datetime.timedelta to subtract n days from today's date. from datetime import timedelta, date def days_ago(n): return date.today() - timedelta(n) days_ago(5) # date(2020, 10, 23) Calculates the day difference between two dates. Subtract start from end and use datetime.timedelta.days to get the day difference. def days_diff(start, end): return (end - start).days from datetime import date days_diff(date(2020, 10, 25), date(2020, 10, 28)) # 3 Calculates the date of n days from today. Use datetime.date.today() to get the current day. Use datetime.timedelta to add n days from today's date. from datetime import timedelta, date def days_from_now(n): return date.today() + timedelta(n) days_from_now(5) # date(2020, 11, 02) Decapitalizes the first letter of a string. Use list slicing and str.lower() to decapitalize the first letter of the string. Use str.join() to combine the lowercase first letter with the rest of the characters. Omit the upper_rest parameter to keep the rest of the string intact, or set it to True to convert to uppercase. def decapitalize(s, upper_rest = False): return ''.join([s[:1].lower(), (s[1:].upper() if upper_rest else s[1:])]) decapitalize('FooBar') # 'fooBar' decapitalize('FooBar', True) # 'fOOBAR' Deep flattens a list. Use recursion. Use isinstance() with collections.abc.Iterable to check if an element is iterable. If it is iterable, apply deep_flatten() recursively, otherwise return [lst]. from collections.abc import Iterable def deep_flatten(lst): return ([a for i in lst for a in deep_flatten(i)] if isinstance(lst, Iterable) else [lst]) deep_flatten([1, [2], [[3], 4], 5]) # [1, 2, 3, 4, 5] Converts an angle from degrees to radians. Use math.pi and the degrees to radians formula to convert the angle from degrees to radians. from math import pi def degrees_to_rads(deg): return (deg * pi) / 180.0 degrees_to_rads(180) # ~3.1416 Invokes the provided function after ms milliseconds. Use time.sleep() to delay the execution of fn by ms / 1000 seconds. from time import sleep def delay(fn, ms, *args): sleep(ms / 1000) return fn(*args) delay(lambda x: print(x), 1000, 'later') # prints 'later' after one second Converts a dictionary to a list of tuples. Use dict.items() and list() to get a list of tuples from the given dictionary. def dict_to_list(d): return list(d.items()) d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4} dict_to_list(d) # [('one', 1), ('three', 3), ('five', 5), ('two', 2), ('four', 4)] Calculates the difference between two iterables, without filtering duplicate values. Create a set from b. Use a list comprehension on a to only keep values not contained in the previously created set, _b. def difference(a, b): _b = set(b) return [item for item in a if item not in _b] difference([1, 2, 3], [1, 2, 4]) # [3] Returns the difference between two lists, after applying the provided function to each list element of both. Create a set, using map() to apply fn to each element in b. Use a list comprehension in combination with fn on a to only keep values not contained in the previously created set, _b. def difference_by(a, b, fn): _b = set(map(fn, b)) return [item for item in a if fn(item) not in _b] from math import floor difference_by([2.1, 1.2], [2.3, 3.4], floor) # [1.2] difference_by([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], lambda v : v['x']) # [ { x: 2 } ] Converts a number to a list of digits. Use map() combined with int on the string representation of n and return a list from the result. def digitize(n): return list(map(int, str(n))) digitize(123) # [1, 2, 3] Returns a list with n elements removed from the left. Use slice notation to remove the specified number of elements from the left. Omit the last argument, n, to use a default value of 1. def drop(a, n = 1): return a[n:] drop([1, 2, 3]) # [2, 3] drop([1, 2, 3], 2) # [3] drop([1, 2, 3], 42) # [] Returns a list with n elements removed from the right. Use slice notation to remove the specified number of elements from the right. Omit the last argument, n, to use a default value of 1. def drop_right(a, n = 1): return a[:-n] drop_right([1, 2, 3]) # [1, 2] drop_right([1, 2, 3], 2) # [1] drop_right([1, 2, 3], 42) # [] Checks if the provided function returns True for every element in the list. Use all() in combination with map() and fn to check if fn returns True for all elements in the list. def every(lst, fn = lambda x: x): return all(map(fn, lst)) every([4, 2, 3], lambda x: x > 1) # True every([1, 2, 3]) # True Returns every nth element in a list. Use slice notation to create a new list that contains every nth element of the given list. def every_nth(lst, nth): return lst[nth - 1::nth] every_nth([1, 2, 3, 4, 5, 6], 2) # [ 2, 4, 6 ] Calculates the factorial of a number. Use recursion. If num is less than or equal to 1, return 1. Otherwise, return the product of num and the factorial of num - 1. Throws an exception if num is a negative or a floating point number. def factorial(num): if not ((num >= 0) and (num % 1 == 0)): raise Exception("Number can't be floating point or negative.") return 1 if num == 0 else num * factorial(num - 1) factorial(6) # 720 unlisted: true Converts Fahrenheit to Celsius. Follow the conversion formula C = (F - 32) * 5/9. def fahrenheit_to_celsius(degrees): return ((degrees - 32) * 5/9) fahrenheit_to_celsius(77) # 25.0 Generates a list, containing the Fibonacci sequence, up until the nth term. Starting with 0 and 1, use list.append() to add the sum of the last two numbers of the list to the end of the list, until the length of the list reaches n. If n is less or equal to 0, return a list containing 0. def fibonacci(n): if n <= 0: return [0] sequence = [0, 1] while len(sequence) <= n: next_value = sequence[len(sequence) - 1] + sequence[len(sequence) - 2] sequence.append(next_value) return sequence fibonacci(7) # [0, 1, 1, 2, 3, 5, 8, 13] Creates a list with the non-unique values filtered out. Use collections.Counter to get the count of each value in the list. Use a list comprehension to create a list containing only the unique values. from collections import Counter def filter_non_unique(lst): return [item for item, count in Counter(lst).items() if count == 1] filter_non_unique([1, 2, 2, 3, 4, 4, 5]) # [1, 3, 5] Creates a list with the unique values filtered out. Use collections.Counter to get the count of each value in the list. Use a list comprehension to create a list containing only the non-unique values. from collections import Counter def filter_unique(lst): return [item for item, count in Counter(lst).items() if count > 1] filter_unique([1, 2, 2, 3, 4, 4, 5]) # [2, 4] Finds the value of the first element in the given list that satisfies the provided testing function. Use a list comprehension and next() to return the first element in lst for which fn returns True. def find(lst, fn): return next(x for x in lst if fn(x)) find([1, 2, 3, 4], lambda n: n % 2 == 1) # 1 Finds the index of the first element in the given list that satisfies the provided testing function. Use a list comprehension, enumerate() and next() to return the index of the first element in lst for which fn returns True. def find_index(lst, fn): return next(i for i, x in enumerate(lst) if fn(x)) find_index([1, 2, 3, 4], lambda n: n % 2 == 1) # 0 Finds the indexes of all elements in the given list that satisfy the provided testing function. Use enumerate() and a list comprehension to return the indexes of the all element in lst for which fn returns True. def find_index_of_all(lst, fn): return [i for i, x in enumerate(lst) if fn(x)] find_index_of_all([1, 2, 3, 4], lambda n: n % 2 == 1) # [0, 2] Finds the first key in the provided dictionary that has the given value. Use dictionary.items() and next() to return the first key that has a value equal to val. def find_key(dict, val): return next(key for key, value in dict.items() if value == val) ages = { 'Peter': 10, 'Isabel': 11, 'Anna': 9, } find_key(ages, 11) # 'Isabel' Finds all keys in the provided dictionary that have the given value. Use dictionary.items(), a generator and list() to return all keys that have a value equal to val. def find_keys(dict, val): return list(key for key, value in dict.items() if value == val) ages = { 'Peter': 10, 'Isabel': 11, 'Anna': 10, } find_keys(ages, 10) # [ 'Peter', 'Anna' ] Finds the value of the last element in the given list that satisfies the provided testing function. Use a list comprehension and next() to return the last element in lst for which fn returns True. def find_last(lst, fn): return next(x for x in lst[::-1] if fn(x)) find_last([1, 2, 3, 4], lambda n: n % 2 == 1) # 3 Finds the index of the last element in the given list that satisfies the provided testing function. Use a list comprehension, enumerate() and next() to return the index of the last element in lst for which fn returns True. def find_last_index(lst, fn): return len(lst) - 1 - next(i for i, x in enumerate(lst[::-1]) if fn(x)) find_last_index([1, 2, 3, 4], lambda n: n % 2 == 1) # 2 Finds the items that are parity outliers in a given list. Use collections.Counter with a list comprehension to count even and odd values in the list. Use collections.Counter.most_common() to get the most common parity. Use a list comprehension to find all elements that do not match the most common parity. from collections import Counter def find_parity_outliers(nums): return [ x for x in nums if x % 2 != Counter([n % 2 for n in nums]).most_common()[0][0] ] find_parity_outliers([1, 2, 3, 4, 6]) # [1, 3] Flattens a list of lists once. Use a list comprehension to extract each value from sub-lists in order. def flatten(lst): return [x for y in lst for x in y] flatten([[1, 2, 3, 4], [5, 6, 7, 8]]) # [1, 2, 3, 4, 5, 6, 7, 8] Executes the provided function once for each list element. Use a for loop to execute fn for each element in itr. def for_each(itr, fn): for el in itr: fn(el) for_each([1, 2, 3], print) # 1 2 3 Executes the provided function once for each list element, starting from the list's last element. Use a for loop in combination with slice notation to execute fn for each element in itr, starting from the last one. def for_each_right(itr, fn): for el in itr[::-1]: fn(el) for_each_right([1, 2, 3], print) # 3 2 1 Creates a dictionary with the unique values of a list as keys and their frequencies as the values. Use collections.defaultdict() to store the frequencies of each unique element. Use dict() to return a dictionary with the unique elements of the list as keys and their frequencies as the values. from collections import defaultdict def frequencies(lst): freq = defaultdict(int) for val in lst: freq[val] += 1 return dict(freq) frequencies(['a', 'b', 'a', 'c', 'a', 'a', 'b']) # { 'a': 4, 'b': 2, 'c': 1 } Converts a date from its ISO-8601 representation. Use datetime.datetime.fromisoformat() to convert the given ISO-8601 date to a datetime.datetime object. from datetime import datetime def from_iso_date(d): return datetime.fromisoformat(d) from_iso_date('2020-10-28T12:30:59.000000') # 2020-10-28 12:30:59 Calculates the greatest common divisor of a list of numbers. Use functools.reduce() and math.gcd() over the given list. from functools import reduce from math import gcd as _gcd def gcd(numbers): return reduce(_gcd, numbers) gcd([8, 36, 28]) # 4 Initializes a list containing the numbers in the specified range where start and end are inclusive and the ratio between two terms is step. Returns an error if step equals 1. Use range(), math.log() and math.floor() and a list comprehension to create a list of the appropriate length, applying the step for each element. Omit the second argument, start, to use a default value of 1. Omit the third argument, step, to use a default value of 2. from math import floor, log def geometric_progression(end, start=1, step=2): return [start * step ** i for i in range(floor(log(end / start) / log(step)) + 1)] geometric_progression(256) # [1, 2, 4, 8, 16, 32, 64, 128, 256] geometric_progression(256, 3) # [3, 6, 12, 24, 48, 96, 192] geometric_progression(256, 1, 4) # [1, 4, 16, 64, 256] Retrieves the value of the nested key indicated by the given selector list from a dictionary or list. Use functools.reduce() to iterate over the selectors list. Apply operator.getitem() for each key in selectors, retrieving the value to be used as the iteratee for the next iteration. from functools import reduce from operator import getitem def get(d, selectors): return reduce(getitem, selectors, d) users = { 'freddy': { 'name': { 'first': 'fred', 'last': 'smith' }, 'postIds': [1, 2, 3] } } get(users, ['freddy', 'name', 'last']) # 'smith' get(users, ['freddy', 'postIds', 1]) # 2 Groups the elements of a list based on the given function. Use collections.defaultdict to initialize a dictionary. Use fn in combination with a for loop and dict.append() to populate the dictionary. Use dict() to convert it to a regular dictionary. from collections import defaultdict def group_by(lst, fn): d = defaultdict(list) for el in lst: d[fn(el)].append(el) return dict(d) from math import floor group_by([6.1, 4.2, 6.3], floor) # {4: [4.2], 6: [6.1, 6.3]} group_by(['one', 'two', 'three'], len) # {3: ['one', 'two'], 5: ['three']} Calculates the Hamming distance between two values. Use the XOR operator (^) to find the bit difference between the two numbers. Use bin() to convert the result to a binary string. Convert the string to a list and use count() of str class to count and return the number of 1 s in it. def hamming_distance(a, b): return bin(a ^ b).count('1') hamming_distance(2, 3) # 1 Checks if there are duplicate values in a flat list. Use set() on the given list to remove duplicates, compare its length with the length of the list. def has_duplicates(lst): return len(lst) != len(set(lst)) x = [1, 2, 3, 4, 5, 5] y = [1, 2, 3, 4, 5] has_duplicates(x) # True has_duplicates(y) # False Checks if two lists contain the same elements regardless of order. Use set() on the combination of both lists to find the unique values. Iterate over them with a for loop comparing the count() of each unique value in each list. Return False if the counts do not match for any element, True otherwise. def have_same_contents(a, b): for v in set(a + b): if a.count(v) != b.count(v): return False return True have_same_contents([1, 2, 4], [2, 4, 1]) # True Returns the head of a list. Use lst[0] to return the first element of the passed list. def head(lst): return lst[0] head([1, 2, 3]) # 1 Converts a hexadecimal color code to a tuple of integers corresponding to its RGB components. Use a list comprehension in combination with int() and list slice notation to get the RGB components from the hexadecimal string. Use tuple() to convert the resulting list to a tuple. def hex_to_rgb(hex): return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4)) hex_to_rgb('FFA501') # (255, 165, 1) Checks if the given number falls within the given range. Use arithmetic comparison to check if the given number is in the specified range. If the second parameter, end, is not specified, the range is considered to be from 0 to start. def in_range(n, start, end = 0): return start <= n <= end if end >= start else end <= n <= start in_range(3, 2, 5) # True in_range(3, 4) # True in_range(2, 3, 5) # False in_range(3, 2) # False Checks if all the elements in values are included in lst. Check if every value in values is contained in lst using a for loop. Return False if any one value is not found, True otherwise. def includes_all(lst, values): for v in values: if v not in lst: return False return True includes_all([1, 2, 3, 4], [1, 4]) # True includes_all([1, 2, 3, 4], [1, 5]) # False Checks if any element in values is included in lst. Check if any value in values is contained in lst using a for loop. Return True if any one value is found, False otherwise. def includes_any(lst, values): for v in values: if v in lst: return True return False includes_any([1, 2, 3, 4], [2, 9]) # True includes_any([1, 2, 3, 4], [8, 9]) # False Returns a list of indexes of all the occurrences of an element in a list. Use enumerate() and a list comprehension to check each element for equality with value and adding i to the result. def index_of_all(lst, value): return [i for i, x in enumerate(lst) if x == value] index_of_all([1, 2, 1, 4, 5, 1], 1) # [0, 2, 5] index_of_all([1, 2, 3, 4], 6) # [] Returns all the elements of a list except the last one. Use lst[:-1] to return all but the last element of the list. def initial(lst): return lst[:-1] initial([1, 2, 3]) # [1, 2] Initializes a 2D list of given width and height and value. Use a list comprehension and range() to generate h rows where each is a list with length h, initialized with val. Omit the last argument, val, to set the default value to None. def initialize_2d_list(w, h, val = None): return [[val for x in range(w)] for y in range(h)] initialize_2d_list(2, 2, 0) # [[0, 0], [0, 0]] Initializes a list containing the numbers in the specified range where start and end are inclusive with their common difference step. Use list() and range() to generate a list of the appropriate length, filled with the desired values in the given range. Omit start to use the default value of 0. Omit step to use the default value of 1. def initialize_list_with_range(end, start = 0, step = 1): return list(range(start, end + 1, step)) initialize_list_with_range(5) # [0, 1, 2, 3, 4, 5] initialize_list_with_range(7, 3) # [3, 4, 5, 6, 7] initialize_list_with_range(9, 0, 2) # [0, 2, 4, 6, 8] Initializes and fills a list with the specified value. Use a list comprehension and range() to generate a list of length equal to n, filled with the desired values. Omit val to use the default value of 0. def initialize_list_with_values(n, val = 0): return [val for x in range(n)] initialize_list_with_values(5, 2) # [2, 2, 2, 2, 2] Returns a list of elements that exist in both lists. Create a set from a and b. Use the built-in set operator & to only keep values contained in both sets, then transform the set back into a list. def intersection(a, b): _a, _b = set(a), set(b) return list(_a & _b) intersection([1, 2, 3], [4, 3, 2]) # [2, 3] Returns a list of elements that exist in both lists, after applying the provided function to each list element of both. Create a set, using map() to apply fn to each element in b. Use a list comprehension in combination with fn on a to only keep values contained in both lists. def intersection_by(a, b, fn): _b = set(map(fn, b)) return [item for item in a if fn(item) in _b] from math import floor intersection_by([2.1, 1.2], [2.3, 3.4], floor) # [2.1] Inverts a dictionary with unique hashable values. Use dictionary.items() in combination with a list comprehension to create a new dictionary with the values and keys inverted. def invert_dictionary(obj): return { value: key for key, value in obj.items() } ages = { 'Peter': 10, 'Isabel': 11, 'Anna': 9, } invert_dictionary(ages) # { 10: 'Peter', 11: 'Isabel', 9: 'Anna' } Checks if a string is an anagram of another string (case-insensitive, ignores spaces, punctuation and special characters). Use str.isalnum() to filter out non-alphanumeric characters, str.lower() to transform each character to lowercase. Use collections.Counter to count the resulting characters for each string and compare the results. from collections import Counter def is_anagram(s1, s2): return Counter( c.lower() for c in s1 if c.isalnum() ) == Counter( c.lower() for c in s2 if c.isalnum() ) is_anagram('#anagram', 'Nag a ram!') # True Checks if the elements of the first list are contained in the second one regardless of order. Use count() to check if any value in a has more occurrences than it has in b. Return False if any such value is found, True otherwise. def is_contained_in(a, b): for v in set(a): if a.count(v) > b.count(v): return False return True is_contained_in([1, 4], [2, 4, 1]) # True unlisted: true Checks if the first numeric argument is divisible by the second one. Use the modulo operator (%) to check if the remainder is equal to 0. def is_divisible(dividend, divisor): return dividend % divisor == 0 is_divisible(6, 3) # True unlisted: true Checks if the given number is even. Check whether a number is odd or even using the modulo (%) operator. Return True if the number is even, False if the number is odd. def is_even(num): return num % 2 == 0 is_even(3) # False unlisted: true Checks if the given number is odd. Checks whether a number is even or odd using the modulo (%) operator. Returns True if the number is odd, False if the number is even. def is_odd(num): return num % 2 != 0 is_odd(3) # True Checks if the provided integer is a prime number. Return False if the number is 0, 1, a negative number or a multiple of 2. Use all() and range() to check numbers from 3 to the square root of the given number. Return True if none divides the given number, False otherwise. from math import sqrt def is_prime(n): if n <= 1 or (n % 2 == 0 and n > 2): return False return all(n % i for i in range(3, int(sqrt(n)) + 1, 2)) is_prime(11) # True Checks if the given date is a weekday. Use datetime.datetime.weekday() to get the day of the week as an integer. Check if the day of the week is less than or equal to 4. Omit the second argument, d, to use a default value of datetime.today(). from datetime import datetime def is_weekday(d = datetime.today()): return d.weekday() <= 4 from datetime import date is_weekday(date(2020, 10, 25)) # False is_weekday(date(2020, 10, 28)) # True Checks if the given date is a weekend. Use datetime.datetime.weekday() to get the day of the week as an integer. Check if the day of the week is greater than 4. Omit the second argument, d, to use a default value of datetime.today(). from datetime import datetime def is_weekend(d = datetime.today()): return d.weekday() > 4 from datetime import date is_weekend(date(2020, 10, 25)) # True is_weekend(date(2020, 10, 28)) # False Converts a string to kebab case. Use re.sub() to replace any - or _ with a space, using the regexp r"(_|-)+". Use re.sub() to match all words in the string, str.lower() to lowercase them. Finally, use str.join() to combine all word using - as the separator. from re import sub def kebab(s): return '-'.join( sub(r"(\s|_|-)+"," ", sub(r"[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+", lambda mo: ' ' + mo.group(0).lower(), s)).split()) kebab('camelCase') # 'camel-case' kebab('some text') # 'some-text' kebab('some-mixed_string With spaces_underscores-and-hyphens') # 'some-mixed-string-with-spaces-underscores-and-hyphens' kebab('AllThe-small Things') # 'all-the-small-things' Checks if the given key exists in a dictionary. Use the in operator to check if d contains key. def key_in_dict(d, key): return (key in d) d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4} key_in_dict(d, 'three') # True Finds the key of the maximum value in a dictionary. Use max() with the key parameter set to dict.get() to find and return the key of the maximum value in the given dictionary. def key_of_max(d): return max(d, key = d.get) key_of_max({'a':4, 'b':0, 'c':13}) # c Finds the key of the minimum value in a dictionary. Use min() with the key parameter set to dict.get() to find and return the key of the minimum value in the given dictionary. def key_of_min(d): return min(d, key = d.get) key_of_min({'a':4, 'b':0, 'c':13}) # b Creates a flat list of all the keys in a flat dictionary. Use dict.keys() to return the keys in the given dictionary. Return a list() of the previous result. def keys_only(flat_dict): return list(flat_dict.keys()) ages = { 'Peter': 10, 'Isabel': 11, 'Anna': 9, } keys_only(ages) # ['Peter', 'Isabel', 'Anna'] unlisted: true Converts kilometers to miles. Follows the conversion formula mi = km * 0.621371. def km_to_miles(km): return km * 0.621371 km_to_miles(8.1) # 5.0331051 Returns the last element in a list. Use lst[-1] to return the last element of the passed list. def last(lst): return lst[-1] last([1, 2, 3]) # 3 Returns the least common multiple of a list of numbers. Use functools.reduce(), math.gcd() and lcm(x,y) = x * y / gcd(x,y) over the given list. from functools import reduce from math import gcd def lcm(numbers): return reduce((lambda x, y: int(x * y / gcd(x, y))), numbers) lcm([12, 7]) # 84 lcm([1, 3, 4, 5]) # 60 Takes any number of iterable objects or objects with a length property and returns the longest one. Use max() with len() as the key to return the item with the greatest length. If multiple objects have the same length, the first one will be returned. def longest_item(*args): return max(args, key = len) longest_item('this', 'is', 'a', 'testcase') # 'testcase' longest_item([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]) # [1, 2, 3, 4, 5] longest_item([1, 2, 3], 'foobar') # 'foobar' Maps the values of a list to a dictionary using a function, where the key-value pairs consist of the original value as the key and the result of the function as the value. Use map() to apply fn to each value of the list. Use zip() to pair original values to the values produced by fn. Use dict() to return an appropriate dictionary. def map_dictionary(itr, fn): return dict(zip(itr, map(fn, itr))) map_dictionary([1, 2, 3], lambda x: x * x) # { 1: 1, 2: 4, 3: 9 } Creates a dictionary with the same keys as the provided dictionary and values generated by running the provided function for each value. Use dict.items() to iterate over the dictionary, assigning the values produced by fn to each key of a new dictionary. def map_values(obj, fn): return dict((k, fn(v)) for k, v in obj.items()) users = { 'fred': { 'user': 'fred', 'age': 40 }, 'pebbles': { 'user': 'pebbles', 'age': 1 } } map_values(users, lambda u : u['age']) # {'fred': 40, 'pebbles': 1} Returns the maximum value of a list, after mapping each element to a value using the provided function. Use map() with fn to map each element to a value using the provided function. Use max() to return the maximum value. def max_by(lst, fn): return max(map(fn, lst)) max_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda v : v['n']) # 8 Returns the index of the element with the maximum value in a list. Use max() and list.index() to get the maximum value in the list and return its index. def max_element_index(arr): return arr.index(max(arr)) max_element_index([5, 8, 9, 7, 10, 3, 0]) # 4 Returns the n maximum elements from the provided list. Use sorted() to sort the list. Use slice notation to get the specified number of elements. Omit the second argument, n, to get a one-element list. If n is greater than or equal to the provided list's length, then return the original list (sorted in descending order). def max_n(lst, n = 1): return sorted(lst, reverse = True)[:n] max_n([1, 2, 3]) # [3] max_n([1, 2, 3], 2) # [3, 2] Finds the median of a list of numbers. Sort the numbers of the list using list.sort(). Find the median, which is either the middle element of the list if the list length is odd or the average of the two middle elements if the list length is even. statistics.median() provides similar functionality to this snippet. def median(list): list.sort() list_length = len(list) if list_length % 2 == 0: return (list[int(list_length / 2) - 1] + list[int(list_length / 2)]) / 2 return float(list[int(list_length / 2)]) median([1, 2, 3]) # 2.0 median([1, 2, 3, 4]) # 2.5 Merges two or more lists into a list of lists, combining elements from each of the input lists based on their positions. Use max() combined with a list comprehension to get the length of the longest list in the arguments. Use range() in combination with the max_length variable to loop as many times as there are elements in the longest list. If a list is shorter than max_length, use fill_value for the remaining items (defaults to None). zip() and itertools.zip_longest() provide similar functionality to this snippet. def merge(*args, fill_value = None): max_length = max([len(lst) for lst in args]) result = [] for i in range(max_length): result.append([ args[k][i] if i < len(args[k]) else fill_value for k in range(len(args)) ]) return result merge(['a', 'b'], [1, 2], [True, False]) # [['a', 1, True], ['b', 2, False]] merge(['a'], [1, 2], [True, False]) # [['a', 1, True], [None, 2, False]] merge(['a'], [1, 2], [True, False], fill_value = '_') # [['a', 1, True], ['_', 2, False]] Merges two or more dictionaries. Create a new dict and loop over dicts, using dictionary.update() to add the key-value pairs from each one to the result. def merge_dictionaries(*dicts): res = dict() for d in dicts: res.update(d) return res ages_one = { 'Peter': 10, 'Isabel': 11, } ages_two = { 'Anna': 9 } merge_dictionaries(ages_one, ages_two) # { 'Peter': 10, 'Isabel': 11, 'Anna': 9 } unlisted: true Converts miles to kilometers. Follows the conversion formula km = mi * 1.609344. def miles_to_km(miles): return miles * 1.609344 miles_to_km(5.03) # 8.09500032 Returns the minimum value of a list, after mapping each element to a value using the provided function. Use map() with fn to map each element to a value using the provided function. Use min() to return the minimum value. def min_by(lst, fn): return min(map(fn, lst)) min_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda v : v['n']) # 2 Returns the index of the element with the minimum value in a list. Use min() and list.index() to obtain the minimum value in the list and then return its index. def min_element_index(arr): return arr.index(min(arr)) min_element_index([3, 5, 2, 6, 10, 7, 9]) # 2 Returns the n minimum elements from the provided list. Use sorted() to sort the list. Use slice notation to get the specified number of elements. Omit the second argument, n, to get a one-element list. If n is greater than or equal to the provided list's length, then return the original list (sorted in ascending order). def min_n(lst, n = 1): return sorted(lst, reverse = False)[:n] min_n([1, 2, 3]) # [1] min_n([1, 2, 3], 2) # [1, 2] Calculates the month difference between two dates. Subtract start from end and use datetime.timedelta.days to get the day difference. Divide by 30 and use math.ceil() to get the difference in months (rounded up). from math import ceil def months_diff(start, end): return ceil((end - start).days / 30) from datetime import date months_diff(date(2020, 10, 28), date(2020, 11, 25)) # 1 Returns the most frequent element in a list. Use set() to get the unique values in lst. Use max() to find the element that has the most appearances. def most_frequent(lst): return max(set(lst), key = lst.count) most_frequent([1, 2, 1, 2, 3, 2, 1, 4, 2]) #2 Generates a string with the given string value repeated n number of times. Repeat the string n times, using the * operator. def n_times_string(s, n): return (s * n) n_times_string('py', 4) #'pypypypy' Checks if the provided function returns True for at least one element in the list. Use all() and fn to check if fn returns False for all the elements in the list. def none(lst, fn = lambda x: x): return all(not fn(x) for x in lst) none([0, 1, 2, 0], lambda x: x >= 2 ) # False none([0, 0, 0]) # True Maps a number from one range to another range. Return num mapped between outMin- outMax from inMin- inMax. def num_to_range(num, inMin, inMax, outMin, outMax): return outMin + (float(num - inMin) / float(inMax - inMin) * (outMax - outMin)) num_to_range(5, 0, 10, 0, 100) # 50.0 Moves the specified amount of elements to the end of the list. Use slice notation to get the two slices of the list and combine them before returning. def offset(lst, offset): return lst[offset:] + lst[:offset] offset([1, 2, 3, 4, 5], 2) # [3, 4, 5, 1, 2] offset([1, 2, 3, 4, 5], -2) # [4, 5, 1, 2, 3] Pads a string on both sides with the specified character, if it's shorter than the specified length. Use str.ljust() and str.rjust() to pad both sides of the given string. Omit the third argument, char, to use the whitespace character as the default padding character. from math import floor def pad(s, length, char = ' '): return s.rjust(floor((len(s) + length)/2), char).ljust(length, char) pad('cat', 8) # ' cat ' pad('42', 6, '0') # '004200' pad('foobar', 3) # 'foobar' Pads a given number to the specified length. Use str.zfill() to pad the number to the specified length, after converting it to a string. def pad_number(n, l): return str(n).zfill(l) pad_number(1234, 6); # '001234' Checks if the given string is a palindrome. Use str.lower() and re.sub() to convert to lowercase and remove non-alphanumeric characters from the given string. Then, compare the new string with its reverse, using slice notation. from re import sub def palindrome(s): s = sub('[\W_]', '', s.lower()) return s == s[::-1] palindrome('taco cat') # True Converts a list of dictionaries into a list of values corresponding to the specified key. Use a list comprehension and dict.get() to get the value of key for each dictionary in lst. def pluck(lst, key): return [x.get(key) for x in lst] simpsons = [ { 'name': 'lisa', 'age': 8 }, { 'name': 'homer', 'age': 36 }, { 'name': 'marge', 'age': 34 }, { 'name': 'bart', 'age': 10 } ] pluck(simpsons, 'age') # [8, 36, 34, 10] Returns the powerset of a given iterable. Use list() to convert the given value to a list. Use range() and itertools.combinations() to create a generator that returns all subsets. Use itertools.chain.from_iterable() and list() to consume the generator and return a list. from itertools import chain, combinations def powerset(iterable): s = list(iterable) return list(chain.from_iterable(combinations(s, r) for r in range(len(s)+1))) powerset([1, 2]) # [(), (1,), (2,), (1, 2)] Converts an angle from radians to degrees. Use math.pi and the radian to degree formula to convert the angle from radians to degrees. from math import pi def rads_to_degrees(rad): return (rad * 180.0) / pi from math import pi rads_to_degrees(pi / 2) # 90.0 Reverses a list or a string. Use slice notation to reverse the list or string. def reverse(itr): return itr[::-1] reverse([1, 2, 3]) # [3, 2, 1] reverse('snippet') # 'teppins' Reverses a number. Use str() to convert the number to a string, slice notation to reverse it and str.replace() to remove the sign. Use float() to convert the result to a number and math.copysign() to copy the original sign. from math import copysign def reverse_number(n): return copysign(float(str(n)[::-1].replace('-', '')), n) reverse_number(981) # 189 reverse_number(-500) # -5 reverse_number(73.6) # 6.37 reverse_number(-5.23) # -32.5 Converts the values of RGB components to a hexadecimal color code. Create a placeholder for a zero-padded hexadecimal value using '{:02X}' and copy it three times. Use str.format() on the resulting string to replace the placeholders with the given values. def rgb_to_hex(r, g, b): return ('{:02X}' * 3).format(r, g, b) rgb_to_hex(255, 165, 1) # 'FFA501' Moves the specified amount of elements to the start of the list. Use slice notation to get the two slices of the list and combine them before returning. def roll(lst, offset): return lst[-offset:] + lst[:-offset] roll([1, 2, 3, 4, 5], 2) # [4, 5, 1, 2, 3] roll([1, 2, 3, 4, 5], -2) # [3, 4, 5, 1, 2] Returns a random element from a list. Use random.choice() to get a random element from lst. from random import choice def sample(lst): return choice(lst) sample([3, 7, 9, 11]) # 9 Randomizes the order of the values of an list, returning a new list. Uses the Fisher-Yates algorithm to reorder the elements of the list. random.shuffle provides similar functionality to this snippet. from copy import deepcopy from random import randint def shuffle(lst): temp_lst = deepcopy(lst) m = len(temp_lst) while (m): m -= 1 i = randint(0, m) temp_lst[m], temp_lst[i] = temp_lst[i], temp_lst[m] return temp_lst foo = [1, 2, 3] shuffle(foo) # [2, 3, 1], foo = [1, 2, 3] Returns a list of elements that exist in both lists. Use a list comprehension on a to only keep values contained in both lists. def similarity(a, b): return [item for item in a if item in b] similarity([1, 2, 3], [1, 2, 4]) # [1, 2] Converts a string to a URL-friendly slug. Use str.lower() and str.strip() to normalize the input string. Use re.sub() to to replace spaces, dashes and underscores with - and remove special characters. import re def slugify(s): s = s.lower().strip() s = re.sub(r'[^\w\s-]', '', s) s = re.sub(r'[\s_-]+', '-', s) s = re.sub(r'^-+|-+$', '', s) return s slugify('Hello World!') # 'hello-world' Converts a string to snake case. Use re.sub() to match all words in the string, str.lower() to lowercase them. Use re.sub() to replace any - characters with spaces. Finally, use str.join() to combine all words using - as the separator. from re import sub def snake(s): return '_'.join( sub('([A-Z][a-z]+)', r' \1', sub('([A-Z]+)', r' \1', s.replace('-', ' '))).split()).lower() snake('camelCase') # 'camel_case' snake('some text') # 'some_text' snake('some-mixed_string With spaces_underscores-and-hyphens') # 'some_mixed_string_with_spaces_underscores_and_hyphens' snake('AllThe-small Things') # 'all_the_small_things' Checks if the provided function returns True for at least one element in the list. Use any() in combination with map() to check if fn returns True for any element in the list. def some(lst, fn = lambda x: x): return any(map(fn, lst)) some([0, 1, 2, 0], lambda x: x >= 2 ) # True some([0, 0, 1, 0]) # True Sorts one list based on another list containing the desired indexes. Use zip() and sorted() to combine and sort the two lists, based on the values of indexes. Use a list comprehension to get the first element of each pair from the result. Use the reverse parameter in sorted() to sort the dictionary in reverse order, based on the third argument. def sort_by_indexes(lst, indexes, reverse=False): return [val for (_, val) in sorted(zip(indexes, lst), key=lambda x: \ x[0], reverse=reverse)] a = ['eggs', 'bread', 'oranges', 'jam', 'apples', 'milk'] b = [3, 2, 6, 4, 1, 5] sort_by_indexes(a, b) # ['apples', 'bread', 'eggs', 'jam', 'milk', 'oranges'] sort_by_indexes(a, b, True) # ['oranges', 'milk', 'jam', 'eggs', 'bread', 'apples'] Sorts the given dictionary by key. Use dict.items() to get a list of tuple pairs from d and sort it using sorted(). Use dict() to convert the sorted list back to a dictionary. Use the reverse parameter in sorted() to sort the dictionary in reverse order, based on the second argument. def sort_dict_by_key(d, reverse = False): return dict(sorted(d.items(), reverse = reverse)) d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4} sort_dict_by_key(d) # {'five': 5, 'four': 4, 'one': 1, 'three': 3, 'two': 2} sort_dict_by_key(d, True) # {'two': 2, 'three': 3, 'one': 1, 'four': 4, 'five': 5} Sorts the given dictionary by value. Use dict.items() to get a list of tuple pairs from d and sort it using a lambda function and sorted(). Use dict() to convert the sorted list back to a dictionary. Use the reverse parameter in sorted() to sort the dictionary in reverse order, based on the second argument.⚠️ NOTICE: Dictionary values must be of the same type. def sort_dict_by_value(d, reverse = False): return dict(sorted(d.items(), key = lambda x: x[1], reverse = reverse)) d = {'one': 1, 'three': 3, 'five': 5, 'two': 2, 'four': 4} sort_dict_by_value(d) # {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5} sort_dict_by_value(d, True) # {'five': 5, 'four': 4, 'three': 3, 'two': 2, 'one': 1} Splits a multiline string into a list of lines. Use str.split() and '\n' to match line breaks and create a list. str.splitlines() provides similar functionality to this snippet. def split_lines(s): return s.split('\n') split_lines('This\nis a\nmultiline\nstring.\n') # ['This', 'is a', 'multiline', 'string.' , ''] Flattens a list, by spreading its elements into a new list. Loop over elements, use list.extend() if the element is a list, list.append() otherwise. def spread(arg): ret = [] for i in arg: ret.extend(i) if isinstance(i, list) else ret.append(i) return ret spread([1, 2, 3, [4, 5, 6], [7], 8, 9]) # [1, 2, 3, 4, 5, 6, 7, 8, 9] Calculates the sum of a list, after mapping each element to a value using the provided function. Use map() with fn to map each element to a value using the provided function. Use sum() to return the sum of the values. def sum_by(lst, fn): return sum(map(fn, lst)) sum_by([{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }], lambda v : v['n']) # 20 Returns the sum of the powers of all the numbers from start to end (both inclusive). Use range() in combination with a list comprehension to create a list of elements in the desired range raised to the given power. Use sum() to add the values together. Omit the second argument, power, to use a default power of 2. Omit the third argument, start, to use a default starting value of 1. def sum_of_powers(end, power = 2, start = 1): return sum([(i) ** power for i in range(start, end + 1)]) sum_of_powers(10) # 385 sum_of_powers(10, 3) # 3025 sum_of_powers(10, 3, 5) # 2925 Returns the symmetric difference between two iterables, without filtering out duplicate values. Create a set from each list. Use a list comprehension on each of them to only keep values not contained in the previously created set of the other. def symmetric_difference(a, b): (_a, _b) = (set(a), set(b)) return [item for item in a if item not in _b] + [item for item in b if item not in _a] symmetric_difference([1, 2, 3], [1, 2, 4]) # [3, 4] Returns the symmetric difference between two lists, after applying the provided function to each list element of both. Create a set by applying fn to each element in every list. Use a list comprehension in combination with fn on each of them to only keep values not contained in the previously created set of the other. def symmetric_difference_by(a, b, fn): (_a, _b) = (set(map(fn, a)), set(map(fn, b))) return [item for item in a if fn(item) not in _b] + [item for item in b if fn(item) not in _a] from math import floor symmetric_difference_by([2.1, 1.2], [2.3, 3.4], floor) # [1.2, 3.4] Returns all elements in a list except for the first one. Use slice notation to return the last element if the list's length is more than 1. Otherwise, return the whole list. def tail(lst): return lst[1:] if len(lst) > 1 else lst tail([1, 2, 3]) # [2, 3] tail([1]) # [1] Returns a list with n elements removed from the beginning. Use slice notation to create a slice of the list with n elements taken from the beginning. def take(itr, n = 1): return itr[:n] take([1, 2, 3], 5) # [1, 2, 3] take([1, 2, 3], 0) # [] Returns a list with n elements removed from the end. Use slice notation to create a slice of the list with n elements taken from the end. def take_right(itr, n = 1): return itr[-n:] take_right([1, 2, 3], 2) # [2, 3] take_right([1, 2, 3]) # [3] Returns the binary representation of the given number. Use bin() to convert a given decimal number into its binary equivalent. def to_binary(n): return bin(n) to_binary(100) # 0b1100100 Combines two lists into a dictionary, where the elements of the first one serve as the keys and the elements of the second one serve as the values. The values of the first list need to be unique and hashable. Use zip() in combination with dict() to combine the values of the two lists into a dictionary. def to_dictionary(keys, values): return dict(zip(keys, values)) to_dictionary(['a', 'b'], [1, 2]) # { a: 1, b: 2 } Returns the hexadecimal representation of the given number. Use hex() to convert a given decimal number into its hexadecimal equivalent. def to_hex(dec): return hex(dec) to_hex(41) # 0x29 to_hex(332) # 0x14c Converts a date to its ISO-8601 representation. Use datetime.datetime.isoformat() to convert the given datetime.datetime object to an ISO-8601 date. from datetime import datetime def to_iso_date(d): return d.isoformat() from datetime import datetime to_iso_date(datetime(2020, 10, 25)) # 2020-10-25T00:00:00 Converts an integer to its roman numeral representation. Accepts value between 1 and 3999 (both inclusive). Create a lookup list containing tuples in the form of (roman value, integer). Use a for loop to iterate over the values in lookup. Use divmod() to update num with the remainder, adding the roman numeral representation to the result. def to_roman_numeral(num): lookup = [ (1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I'), ] res = '' for (n, roman) in lookup: (d, num) = divmod(num, n) res += roman * d return res to_roman_numeral(3) # 'III' to_roman_numeral(11) # 'XI' to_roman_numeral(1998) # 'MCMXCVIII' Transposes a two-dimensional list. Use *lst to get the provided list as tuples. Use zip() in combination with list() to create the transpose of the given two-dimensional list. def transpose(lst): return list(zip(*lst)) transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) # [(1, 4, 7, 10), (2, 5, 8, 11), (3, 6, 9, 12)] Builds a list, using an iterator function and an initial seed value. The iterator function accepts one argument ( seed) and must always return a list with two elements ([ value, nextSeed]) or False to terminate. Use a generator function, fn_generator, that uses a while loop to call the iterator function and yield the value until it returns False. Use a list comprehension to return the list that is produced by the generator, using the iterator function. def unfold(fn, seed): def fn_generator(val): while True: val = fn(val[1]) if val == False: break yield val[0] return [i for i in fn_generator([None, seed])] f = lambda n: False if n > 50 else [-n, n + 10] unfold(f, 10) # [-10, -20, -30, -40, -50] Returns every element that exists in any of the two lists once. Create a set with all values of a and b and convert to a list. def union(a, b): return list(set(a + b)) union([1, 2, 3], [4, 3, 2]) # [1, 2, 3, 4] Returns every element that exists in any of the two lists once, after applying the provided function to each element of both. Create a set by applying fn to each element in a. Use a list comprehension in combination with fn on b to only keep values not contained in the previously created set, _a. Finally, create a set from the previous result and a and transform it into a list def union_by(a, b, fn): _a = set(map(fn, a)) return list(set(a + [item for item in b if fn(item) not in _a])) from math import floor union_by([2.1], [1.2, 2.3], floor) # [2.1, 1.2] Returns the unique elements in a given list. Create a set from the list to discard duplicated values, then return a list from it. def unique_elements(li): return list(set(li)) unique_elements([1, 2, 2, 3, 4, 3]) # [1, 2, 3, 4] Returns a flat list of all the values in a flat dictionary. Use dict.values() to return the values in the given dictionary. Return a list() of the previous result. def values_only(flat_dict): return list(flat_dict.values()) ages = { 'Peter': 10, 'Isabel': 11, 'Anna': 9, } values_only(ages) # [10, 11, 9] Returns the weighted average of two or more numbers. Use sum() to sum the products of the numbers by their weight and to sum the weights. Use zip() and a list comprehension to iterate over the pairs of values and weights. def weighted_average(nums, weights): return sum(x * y for x, y in zip(nums, weights)) / sum(weights) weighted_average([1, 2, 3], [0.6, 0.2, 0.3]) # 1.72727 Tests a value, x, against a testing function, conditionally applying a function. Check if the value of predicate(x) is True and if so return when_true(x), otherwise return x. def when(predicate, when_true): return lambda x: when_true(x) if predicate(x) else x double_even_numbers = when(lambda x: x % 2 == 0, lambda x : x * 2) double_even_numbers(2) # 4 double_even_numbers(1) # 1 Converts a given string into a list of words. Use re.findall() with the supplied pattern to find all matching substrings. Omit the second argument to use the default regexp, which matches alphanumeric and hyphens. import re def words(s, pattern = '[a-zA-Z-]+'): return re.findall(pattern, s) words('I love Python!!') # ['I', 'love', 'Python'] words('python, javaScript & coffee') # ['python', 'javaScript', 'coffee'] words('build -q --out one-item', r'\b[a-zA-Z-]+\b') # ['build', 'q', 'out', 'one-item']
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Python General Notes Python Notes https://lambda-6.gitbook.io/python/ This Gitbook As A Website https://ds-unit-5-lambda.netlify.app/ https://bryan-guner.gitbook.io/datastructures-in-pytho/ https://replit.com/@bgoonz/DATASTRUCPYTHONNOTES-2 Keywords:***and del for is raise assert elif from lambda return break else global not try class except if or while continue exec import pass def finally in print*** py-notes.pdf https://bryan-guner.gitbook.io/notesarchive/ DOCS: https://docs.python.org/3/ import math def say_hi(name): """<---- Multi-Line Comments and Docstrings This is where you put your content for help() to inform the user about what your function does and how to use it """ print(f"Hello {name}!") print(say_hi("Bryan")) # Should get the print inside the function, then None # Boolean Values # Work the same as in JS, except they are title case: True and False a = True b = False # Logical Operators # ! = not, || = or, && = and print(True and True) print(True and not True) print(True or True) # Truthiness - Everything is True except... # False - None, False, '', [], (), set(), range(0) # Number Values # Integers are numbers without a floating decimal point print(type(3)) # type returns the type of whatever argument you pass in # Floating Point values are numbers with a floating decimal point print(type(3.5)) # Type Casting # You can convert between ints and floats (along with other types...) print(float(3)) # If you convert a float to an int, it will truncate the decimal print(int(4.5)) print(type(str(3))) # Python does not automatically convert types like JS # print(17.0 + ' heyooo ' + 17) # TypeError # Arithmetic Operators # ** - exponent (comparable to Math.pow(num, pow)) # // - integer division # There is no ++ or -- in Python # String Values # We can use single quotes, double quotes, or f'' for string formats # We can use triple single quotes for multiline strings print( """This here's a story All about how My life got twist Turned upside down """ ) # Three double quotes can also be used, but we typically reserve these for # multi-line comments and function docstrings (refer to lines 6-9)(Nice :D) # We use len() to get the length of something print(len("Bryan G")) # 7 characters print(len(["hey", "ho", "hey", "hey", "ho"])) # 5 list items print(len({1, 2, 3, 4, 5, 6, 7, 9})) # 8 set items # We can index into strings, list, etc..self. name = "Bryan" for i in range(len(name)): print(name[i]) # B, r, y, a, n # We can index starting from the end as well, with negatives occupation = "Full Stack Software Engineer" print(occupation[-3]) # e # We can also get ranges in the index with the [start:stop:step] syntax print(occupation[0:4:1]) # step and stop are optional, stop is exclusive print(occupation[::4]) # beginning to end, every 4th letter print(occupation[4:14:2]) # Let's get weird with it! # NOTE: Indexing out of range will give you an IndexError # We can also get the index og things with the .index() method, similar to indexOf() print(occupation.index("Stack")) print(["Mike", "Barry", "Cole", "James", "Mark"].index("Cole")) # We can count how many times a substring/item appears in something as well print(occupation.count("S")) print( """Now this here's a story all about how My life got twist turned upside down I forget the rest but the the the potato smells like the potato""".count( "the" ) ) # We concatenate the same as Javascript, but we can also multiply strings print("dog " + "show") print("ha" * 10) # We can use format for a multitude of things, from spaces to decimal places first_name = "Bryan" last_name = "Guner" print("Your name is {0} {1}".format(first_name, last_name)) # Useful String Methods print("Hello".upper()) # HELLO print("Hello".lower()) # hello print("HELLO".islower()) # False print("HELLO".isupper()) # True print("Hello".startswith("he")) # False print("Hello".endswith("lo")) # True print("Hello There".split()) # [Hello, There] print("hello1".isalpha()) # False, must consist only of letters print("hello1".isalnum()) # True, must consist of only letters and numbers print("3215235123".isdecimal()) # True, must be all numbers # True, must consist of only spaces/tabs/newlines print(" \\n ".isspace()) # False, index 0 must be upper case and the rest lower print("Bryan Guner".istitle()) print("Michael Lee".istitle()) # True! # Duck Typing - If it walks like a duck, and talks like a duck, it must be a duck # Assignment - All like JS, but there are no special keywords like let or const a = 3 b = a c = "heyoo" b = ["reassignment", "is", "fine", "G!"] # Comparison Operators - Python uses the same equality operators as JS, but no === # < - Less than # > - Greater than # <= - Less than or Equal # >= - Greater than or Equal # == - Equal to # != - Not equal to # is - Refers to exact same memory location # not - ! # Precedence - Negative Signs(not) are applied first(part of each number) # - Multiplication and Division(and) happen next # - Addition and Subtraction(or) are the last step # NOTE: Be careful when using not along with == print(not a == b) # True # print(a == not b) # Syntax Error print(a == (not b)) # This fixes it. Answer: False # Python does short-circuit evaluation # Assignment Operators - Mostly the same as JS except Python has **= and //= (int division) # Flow Control Statements - if, while, for # Note: Python smushes 'else if' into 'elif'! if 10 < 1: print("We don't get here") elif 10 < 5: print("Nor here...") else: print("Hey there!") # Looping over a string for c in "abcdefgh": print(c) # Looping over a range for i in range(5): print(i + 1) # Looping over a list lst = [1, 2, 3, 4] for i in lst: print(i) # Looping over a dictionary spam = {"color": "red", "age": 42, "items": [(1, "hey"), (2, "hooo!")]} for v in spam.values(): print(v) # Loop over a list of tuples and destructuring the values # Assuming spam.items returns a list of tuples each containing two items (k, v) for k, v in spam.items(): print(f"{k}: {v}") # While loops as long as the condition is True # - Exit loop early with break # - Exit iteration early with continue spam = 0 while True: print("Sike That's the wrong Numba") spam += 1 if spam < 5: continue break # Functions - use def keyword to define a function in Python def printCopyright(): print("Copyright 2021, Bgoonz") # Lambdas are one liners! (Should be at least, you can use parenthesis to disobey) def avg(num1, num2): return print(num1 + num2) avg(1, 2) # Calling it with keyword arguments, order does not matter avg(num2=20, num1=1252) printCopyright() # We can give parameters default arguments like JS def greeting(name, saying="Hello"): print(saying, name) greeting("Mike") # Hello Mike greeting("Bryan", saying="Hello there...") # A common gotcha is using a mutable object for a default parameter # All invocations of the function reference the same mutable object def append_item(item_name, item_list=[]): # Will it obey and give us a new list? item_list.append(item_name) return item_list # Uses same item list unless otherwise stated which is counterintuitive print(append_item("notebook")) print(append_item("notebook")) print(append_item("notebook", [])) # Errors - Unlike JS, if we pass the incorrect amount of arguments to a function, # it will throw an error # avg(1) # TypeError # avg(1, 2, 2) # TypeError # ----------------------------------- DAY 2 ---------------------------------------- # Functions - * to get rest of position arguments as tuple # - ** to get rest of keyword arguments as a dictionary # Variable Length positional arguments def add(a, b, *args): # args is a tuple of the rest of the arguments total = a + b for n in args: total += n return total print(add(1, 2)) # args is None, returns 3 print(add(1, 2, 3, 4, 5, 6)) # args is (3, 4, 5, 6), returns 21 # Variable Length Keyword Arguments def print_names_and_countries(greeting, **kwargs): # kwargs is a dictionary of the rest of the keyword arguments for k, v in kwargs.items(): print(greeting, k, "from", v) print_names_and_countries( "Hey there", Monica="Sweden", Mike="The United States", Mark="China" ) # We can combine all of these together def example2(arg1, arg2, *args, kw_1="cheese", kw_2="horse", **kwargs): pass # Lists are mutable arrays empty_list = [] roomates = ["Beau", "Delynn"] # List built-in function makes a list too specials = list() # We can use 'in' to test if something is in the list, like 'includes' in JS print(1 in [1, 2, 4]) # True print(2 in [1, 3, 5]) # False # Dictionaries - Similar to JS POJO's or Map, containing key value pairs a = {"one": 1, "two": 2, "three": 3} b = dict(one=1, two=2, three=3) # Can use 'in' on dictionaries too (for keys) print("one" in a) # True print(3 in b) # False # Sets - Just like JS, unordered collection of distinct objects bedroom = {"bed", "tv", "computer", "clothes", "playstation 4"} # bedroom = set("bed", "tv", "computer", "clothes", "playstation 5") school_bag = set( ["book", "paper", "pencil", "pencil", "book", "book", "book", "eraser"] ) print(school_bag) print(bedroom) # We can use 'in' on sets as wel print(1 in {1, 2, 3}) # True print(4 in {1, 3, 5}) # False # Tuples are immutable lists of items time_blocks = ("AM", "PM") colors = "red", "green", "blue" # Parenthesis not needed but encouraged # The tuple built-in function can be used to convert things to tuples print(tuple("abc")) print(tuple([1, 2, 3])) # 'in' may be used on tuples as well print(1 in (1, 2, 3)) # True print(5 in (1, 4, 3)) # False # Ranges are immutable lists of numbers, often used with for loops # - start - default: 0, first number in sequence # - stop - required, next number past last number in sequence # - step - default: 1, difference between each number in sequence range1 = range(5) # [0,1,2,3,4] range2 = range(1, 5) # [1,2,3,4] range3 = range(0, 25, 5) # [0,5,10,15,20] range4 = range(0) # [] for i in range1: print(i) # Built-in functions: # Filter def isOdd(num): return num % 2 == 1 filtered = filter(isOdd, [1, 2, 3, 4]) print(list(filtered)) for num in filtered: print(f"first way: {num}") print("--" * 20) [print(f"list comprehension: {i}") for i in [1, 2, 3, 4, 5, 6, 7, 8] if i % 2 == 1] # Map def toUpper(str): return str.upper() upperCased = map(toUpper, ["a", "b", "c", "d"]) print(list(upperCased)) # Sorted sorted_items = sorted(["john", "tom", "sonny", "Mike"]) print(list(sorted_items)) # Notice uppercase comes before lowercase # Using a key function to control the sorting and make it case insensitive sorted_items = sorted(["john", "tom", "sonny", "Mike"], key=str.lower) print(sorted_items) # You can also reverse the sort sorted_items = sorted(["john", "tom", "sonny", "Mike"], key=str.lower, reverse=True) print(sorted_items) # Enumerate creates a tuple with an index for what you're enumerating quarters = ["First", "Second", "Third", "Fourth"] print(list(enumerate(quarters))) print(list(enumerate(quarters, start=1))) # Zip takes list and combines them as key value pairs, or really however you need keys = ("Name", "Email") values = ("Buster", "cheetoh@johhnydepp.com") zipped = zip(keys, values) print(list(zipped)) # You can zip more than 2 x_coords = [0, 1, 2, 3, 4] y_coords = [4, 6, 10, 9, 10] z_coords = [20, 10, 5, 9, 1] coords = zip(x_coords, y_coords, z_coords) print(list(coords)) # Len reports the length of strings along with list and any other object data type # doing this to save myself some typing def print_len(item): return print(len(item)) print_len("Mike") print_len([1, 5, 2, 10, 3, 10]) print_len({1, 5, 10, 9, 10}) # 4 because there is a duplicate here (10) print_len((1, 4, 10, 9, 20)) # Max will return the max number in a given scenario print(max(1, 2, 35, 1012, 1)) # Min print(min(1, 5, 2, 10)) print(min([1, 4, 7, 10])) # Sum print(sum([1, 2, 4])) # Any print(any([True, False, False])) print(any([False, False, False])) # All print(all([True, True, False])) print(all([True, True, True])) # Dir returns all the attributes of an object including it's methods and dunder methods user = {"Name": "Bob", "Email": "bob@bob.com"} print(dir(user)) # Importing packages and modules # - Module - A Python code in a file or directory # - Package - A module which is a directory containing an __init__.py file # - Submodule - A module which is contained within a package # - Name - An exported function, class, or variable in a module # Unlike JS, modules export ALL names contained within them without any special export key # Assuming we have the following package with four submodules # math # | __init__.py # | addition.py # | subtraction.py # | multiplication.py # | division.py # If we peek into the addition.py file we see there's an add function # addition.py # We can import 'add' from other places because it's a 'name' and is automatically exported # def add(num1, num2): # return num1 + num2 # Notice the . syntax because this package can import it's own submodules. # Our __init__.py has the following files # This imports the 'add' function # And now it's also re-exported in here as well # from .addition import add # These import and re-export the rest of the functions from the submodule # from .subtraction import subtract # from .division import divide # from .multiplication import multiply # So if we have a script.py and want to import add, we could do it many ways # This will load and execute the 'math/__init__.py' file and give # us an object with the exported names in 'math/__init__.py' # print(math.add(1,2)) # This imports JUST the add from 'math/__init__.py' # from math import add # print(add(1, 2)) # This skips importing from 'math/__init__.py' (although it still runs) # and imports directly from the addition.py file # from math.addition import add # This imports all the functions individually from 'math/__init__.py' # from math import add, subtract, multiply, divide # print(add(1, 2)) # print(subtract(2, 1)) # This imports 'add' renames it to 'add_some_numbers' # from math import add as add_some_numbers # --------------------------------------- DAY 3 --------------------------------------- # Classes, Methods, and Properties class AngryBird: # Slots optimize property access and memory usage and prevent you # from arbitrarily assigning new properties the instance __slots__ = ["_x", "_y"] # Constructor def __init__(self, x=0, y=0): # Doc String """ Construct a new AngryBird by setting it's position to (0, 0) """ # Instance Variables self._x = x self._y = y # Instance Method def move_up_by(self, delta): self._y += delta # Getter @property def x(self): return self._x # Setter @x.setter def x(self, value): if value < 0: value = 0 self._x = value @property def y(self): return self._y @y.setter def y(self, value): self._y = value # Dunder Repr... called by 'print' def __repr__(self): return f"<AngryBird ({self._x}, {self._y})>" # JS to Python Classes cheat table # JS Python # constructor() def __init__(self): # super() super().__init__() # this.property self.property # this.method self.method() # method(arg1, arg2){} def method(self, arg1, ...) # get someProperty(){} @property # set someProperty(){} @someProperty.setter # List Comprehensions are a way to transform a list from one format to another # - Pythonic Alternative to using map or filter # - Syntax of a list comprehension # - new_list = [value loop condition] # Using a for loop squares = [] for i in range(10): squares.append(i ** 2) print(squares) # value = i ** 2 # loop = for i in range(10) squares = [i ** 2 for i in range(10)] print(list(squares)) sentence = "the rocket came back from mars" vowels = [character for character in sentence if character in "aeiou"] print(vowels) # You can also use them on dictionaries. We can use the items() method # for the dictionary to loop through it getting the keys and values out at once person = {"name": "Corina", "age": 32, "height": 1.4} # This loops through and capitalizes the first letter of all keys newPerson = {key.title(): value for key, value in person.items()} print(list(newPerson.items())) 2.1.7 Indentation Leading whitespace (spaces and tabs) at the beginning of a logical line is used to compute the indentation level of the line, which in turn is used to determine the grouping of statements. First, tabs are replaced (from left to right) by one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix). The total number of spaces preceding the first non-blank character then determines the line's indentation. Indentation cannot be split over multiple physical lines using backslashes; the whitespace up to the first backslash determines the indentation. Cross-platform compatibility note: because of the nature of text editors on non-UNIX platforms, it is unwise to use a mixture of spaces and tabs for the indentation in a single source file. A formfeed character may be present at the start of the line; it will be ignored for the indentation calculations above. Formfeed characters occurring elsewhere in the leading whitespace have an undefined effect (for instance, they may reset the space count to zero). The indentation levels of consecutive lines are used to generate INDENT and DEDENT tokens, using a stack, as follows. Before the first line of the file is read, a single zero is pushed on the stack; this will never be popped off again. The numbers pushed on the stack will always be strictly increasing from bottom to top. At the beginning of each logical line, the line's indentation level is compared to the top of the stack. If it is equal, nothing happens. If it is larger, it is pushed on the stack, and one INDENT token is generated. If it is smaller, it must be one of the numbers occurring on the stack; all numbers on the stack that are larger are popped off, and for each number popped off a DEDENT token is generated. At the end of the file, a DEDENT token is generated for each number remaining on the stack that is larger than zero. Here is an example of a correctly (though confusingly) indented piece of Python code: def perm(l): # Compute the list of all permutations of l if len(l) <= 1: return [l] r = [] for i in range(len(l)): s = l[:i] + l[i+1:] p = perm(s) for x in p: r.append(l[i:i+1] + x) return r The following example shows various indentation errors: `def perm(l): # error: first line indented for i in range(len(l)): # error: not indented s = l[:i] + l[i+1:] p = perm(l[:i] + l[i+1:]) # error: unexpected indent for x in p: r.append(l[i:i+1] + x) return r # error: inconsistent dedent` (Actually, the first three errors are detected by the parser; only the last error is found by the lexical analyzer -- the indentation of return r does not match a level popped off the stack.) https://ds-unit-5-lambda.netlify.app/ Python Study Guide for a JavaScript Programmer Bryan Guner Mar 5 · 15 min read Applications of Tutorial & Cheat Sheet Respectivley (At Bottom Of Tutorial): Basics PEP8 : Python Enhancement Proposals, style-guide for Python. print is the equivalent of console.log.'print() == console.log()'** is used to make comments in your code.** def foo(): """ The foo function does many amazing things that you should not question. Just accept that it exists and use it with caution. """ secretThing() Python has a built in help function that let's you see a description of the source code without having to navigate to it… “-SickNasty … Autor Unknown” Numbers Python has three types of numbers: Integer Positive and Negative Counting Numbers. No Decimal Point Created by a literal non-decimal point number … or … with the int() constructor. print(3) # => 3 print(int(19)) # => 19 print(int()) # => 0 3. Complex Numbers Consist of a real part and imaginary part. Boolean is a subtype of integer in Python.🤷‍♂️ If you came from a background in JavaScript and learned to accept the premise(s) of the following meme… Than I am sure you will find the means to suspend your disbelief. print(2.24) # => 2.24 print(2.) # => 2.0 print(float()) # => 0.0 print(27e-5) # => 0.00027 KEEP IN MIND: The i is switched to a j in programming. T* his is because the letter i is common place as the de facto index for any and all enumerable entities so it just makes sense not to compete for name- space when there's another 25 letters that don't get used for every loop under the sun. My most medium apologies to Leonhard Euler.* print(7j) # => 7j print(5.1+7.7j)) # => 5.1+7.7j print(complex(3, 5)) # => 3+5j print(complex(17)) # => 17+0j print(complex()) # => 0j Type Casting : The process of converting one number to another.# Using Float print(17) # => 17 print(float(17)) # => 17.0# Using Int print(17.0) # => 17.0 print(int(17.0)) # => 17# Using Str print(str(17.0) + ' and ' + str(17)) # => 17.0 and 17 The arithmetic operators are the same between JS and Python, with two additions:“**” : Double asterisk for exponent.“//” : Integer Division. There are no spaces between math operations in Python. Integer Division gives the other part of the number from Module; it is a way to do round down numbers replacing Math.floor() in JS. There are no ++ and - in Python, the only shorthand operators are: Strings Python uses both single and double quotes. You can escape strings like so 'Jodi asked, "What\\'s up, Sam?"' Multiline strings use triple quotes. print('''My instructions are very long so to make them more readable in the code I am putting them on more than one line. I can even include "quotes" of any kind because they won't get confused with the end of the string!''') Use the len() function to get the length of a string. print(len(“Spaghetti”)) # => 9 Python uses zero-based indexing Python allows negative indexing (thank god!) print(“Spaghetti”[-1]) # => i print(“Spaghetti”[-4]) # => e Python let's you use ranges You can think of this as roughly equivalent to the slice method called on a JavaScript object or string… (mind you that in JS … strings are wrapped in an object (under the hood)… upon which the string methods are actually called. As a immutable privative type by textbook definition, a string literal could not hope to invoke most of it's methods without violating the state it was bound to on initialization if it were not for this bit of syntactic sugar.) print(“Spaghetti”[1:4]) # => pag print(“Spaghetti”[4:-1]) # => hett print(“Spaghetti”[4:4]) # => (empty string) The end range is exclusive just like slice in JS.# Shortcut to get from the beginning of a string to a certain index. print("Spaghetti"[:4]) # => Spag print("Spaghetti"[:-1]) # => Spaghett# Shortcut to get from a certain index to the end of a string. print("Spaghetti"[1:]) # => paghetti print("Spaghetti"[-4:]) # => etti The index string function is the equiv. of indexOf() in JS print("Spaghetti".index("h")) # => 4 print("Spaghetti".index("t")) # => 6 The count function finds out how many times a substring appears in a string… pretty nifty for a hard coded feature of the language. print("Spaghetti".count("h")) # => 1 print("Spaghetti".count("t")) # => 2 print("Spaghetti".count("s")) # => 0 print('''We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard, because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too. '''.count('the ')) # => 4 You can use + to concatenate strings, just like in JS. You can also use “*” to repeat strings or multiply strings. Use the format() function to use placeholders in a string to input values later on. first_name = "Billy" last_name = "Bob" print('Your name is {0} {1}'.format(first_name, last_name)) # => Your name is Billy Bob Shorthand way to use format function is: print(f'Your name is {first_name} {last_name}') Some useful string methods. Note that in JS join is used on an Array, in Python it is used on String. There are also many handy testing methods. Variables and Expressions Duck-Typing : Programming Style which avoids checking an object's type to figure out what it can do. Duck Typing is the fundamental approach of Python. Assignment of a value automatically declares a variable. a = 7 b = 'Marbles' print(a) # => 7 print(b) # => Marbles You can chain variable assignments to give multiple var names the same value. Use with caution as this is highly unreadable count = max = min = 0 print(count) # => 0 print(max) # => 0 print(min) # => 0 The value and type of a variable can be re-assigned at any time. a = 17 print(a) # => 17 a = 'seventeen' print(a) # => seventeen * does not exist in Python, but you can 'create' it like so:* Python replaces null with none.* is an object and can be directly assigned to a variable.* Using none is a convenient way to check to see why an action may not be operating correctly in your program. Boolean Data Type One of the biggest benefits of Python is that it reads more like English than JS does.# Logical AND print(True and True) # => True print(True and False) # => False print(False and False) # => False# Logical OR print(True or True) # => True print(True or False) # => True print(False or False) # => False# Logical NOT print(not True) # => False print(not False and True) # => True print(not True or False) # => False By default, Python considers an object to be true UNLESS it is one of the following: Constant None or False Zero of any numeric type. Empty Sequence or Collection. True and False must be capitalized Comparison Operators Python uses all the same equality operators as JS. In Python, equality operators are processed from left to right. Logical operators are processed in this order: NOT AND OR Just like in JS, you can use parentheses to change the inherent order of operations.Short Circuit : Stopping a program when a true or false has been reached. Identity vs Equality**** print (2 == '2') # => False print (2 is '2') # => Falseprint ("2" == '2') # => True print ("2" is '2') # => True# There is a distinction between the number types. print (2 == 2.0) # => True print (2 is 2.0) # => False In the Python community it is better to use is and is not over == or != If Statements if name == 'Monica': print('Hi, Monica.')if name == 'Monica': print('Hi, Monica.')else: print('Hello, stranger.')if name == 'Monica': print('Hi, Monica.')elif age < 12: print('You are not Monica, kiddo.')elif age > 2000: print('Unlike you, Monica is not an undead, immortal vampire.')elif age > 100: print('You are not Monica, grannie.') Remember the order of elif statements matter. While Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 Break statement also exists in Python. spam = 0 while True: print('Hello, world.') spam = spam + 1 if spam >= 5: break As are continue statements spam = 0 while True: print('Hello, world.') spam = spam + 1 if spam < 5: continue break Try/Except Statements Python equivalent to try/catch a = 321 try: print(len(a)) except: print('Silently handle error here') # Optionally include a correction to the issue a = str(a) print(len(a)a = '321' try: print(len(a)) except: print('Silently handle error here') # Optionally include a correction to the issue a = str(a) print(len(a)) You can name an error to give the output more specificity. a = 100 b = 0 try: c = a / b except ZeroDivisionError: c = None print(c) You can also use the pass commmand to by pass a certain error. a = 100 b = 0 try: print(a / b) except ZeroDivisionError: pass The pass method won't allow you to bypass every single error so you can chain an exception series like so: a = 100 # b = "5" try: print(a / b) except ZeroDivisionError: pass except (TypeError, NameError): print("ERROR!") You can use an else statement to end a chain of except statements.# tuple of file names files = ('one.txt', 'two.txt', 'three.txt')# simple loop for filename in files: try: # open the file in read mode f = open(filename, 'r') except OSError: # handle the case where file does not exist or permission is denied print('cannot open file', filename) else: # do stuff with the file object (f) print(filename, 'opened successfully') print('found', len(f.readlines()), 'lines') f.close() finally is used at the end to clean up all actions under any circumstance. def divide(x, y): try: result = x / y except ZeroDivisionError: print("Cannot divide by zero") else: print("Result is", result) finally: print("Finally...") Using duck typing to check to see if some value is able to use a certain method.# Try a number - nothing will print out a = 321 if hasattr(a, '__len__'): print(len(a))# Try a string - the length will print out (4 in this case) b = "5555" if hasattr(b, '__len__'): print(len(b)) Pass Pass Keyword is required to write the JS equivalent of : if (true) { }while (true) {}if True: passwhile True: pass Functions Function definition includes: The def keyword The name of the function A list of parameters enclosed in parentheses. A colon at the end of the line. One tab indentation for the code to run. You can use default parameters just like in JS def greeting(name, saying="Hello"): print(saying, name)greeting("Monica") # Hello Monicagreeting("Barry", "Hey") # Hey Barry Keep in mind, default parameters must always come after regular parameters.# THIS IS BAD CODE AND WILL NOT RUN def increment(delta=1, value): return delta + value You can specify arguments by name without destructuring in Python. def greeting(name, saying="Hello"): print(saying, name)# name has no default value, so just provide the value # saying has a default value, so use a keyword argument greeting("Monica", saying="Hi") The lambda keyword is used to create anonymous functions and are supposed to be one-liners. toUpper = lambda s: s.upper() Notes Formatted Strings Remember that in Python join() is called on a string with an array/list passed in as the argument.Python has a very powerful formatting engine.format() is also applied directly to strings. shopping_list = ['bread','milk','eggs'] print(','.join(shopping_list)) Comma Thousands Separator print('{:,}'.format(1234567890)) '1,234,567,890' Date and Time d = datetime.datetime(2020, 7, 4, 12, 15, 58) print('{:%Y-%m-%d %H:%M:%S}'.format(d)) '2020–07–04 12:15:58' Percentage points = 190 total = 220 print('Correct answers: {:.2%}'.format(points/total)) Correct answers: 86.36% Data Tables width=8 print(' decimal hex binary') print('-'*27) for num in range(1,16): for base in 'dXb': print('{0:{width}{base}}'.format(num, base=base, width=width), end=' ') print() Getting Input from the Command Line Python runs synchronously, all programs and processes will stop when listening for a user input. The input function shows a prompt to a user and waits for them to type 'ENTER'. Scripts vs Programs Programming Script : A set of code that runs in a linear fashion. The largest difference between scripts and programs is the level of complexity and purpose. Programs typically have many UI's. **Python can be used to display html, css, and JS.** It is common to use Python as an API (Application Programming Interface) Structured Data Sequence : The most basic data structure in Python where the index determines the order. List-Tuple-Range-Collections : Unordered data structures, hashable values. Dictionaries-Sets-Iterable : Generic name for a sequence or collection; any object that can be iterated through.Can be mutable or immutable.Built In Data Types Lists are the python equivalent of arrays. empty_list = [] departments = ['HR','Development','Sales','Finance','IT','Customer Support'] You can instantiate specials = list() Test if a value is in a list. print(1 in [1, 2, 3]) #> True print(4 in [1, 2, 3]) #> False # Tuples : Very similar to lists, but they are immutable Instantiated with parentheses time_blocks = ('AM','PM') Sometimes instantiated without colors = 'red','blue','green' numbers = 1, 2, 3 Tuple() built in can be used to convert other data into a tuple tuple('abc') # returns ('a', 'b', 'c') tuple([1,2,3]) # returns (1, 2, 3) # Think of tuples as constant variables. Ranges : A list of numbers which can't be changed; often used with for loops. Declared using one to three parameters. Start : opt. default 0, first # in sequence.Stop : required next number past the last number in the sequence.Step : opt. default 1, difference between each number in the sequence. range(5) # [0, 1, 2, 3, 4] range(1,5) # [1, 2, 3, 4] range(0, 25, 5) # [0, 5, 10, 15, 20] range(0) # [ ] for let (i = 0; i < 5; i++) for let (i = 1; i < 5; i++) for let (i = 0; i < 25; i+=5) for let(i = 0; i = 0; i++) # Keep in mind that stop is not included in the range. Dictionaries : Mappable collection where a hashable value is used as a key to ref. an object stored in the dictionary. Mutable. a = {'one':1, 'two':2, 'three':3} b = dict(one=1, two=2, three=3) c = dict([('two', 2), ('one', 1), ('three', 3)]) # a, b, and c are all equal Declared with curly braces of the built in dict() Benefit of dictionaries in Python is that it doesn't matter how it is defined, if the keys and values are the same the dictionaries are considered equal. Use the in operator to see if a key exists in a dictionary. Sets : Unordered collection of distinct objects; objects that need to be hashable. Always be unique, duplicate items are auto dropped from the set. Common Uses: Removing DuplicatesMembership TestingMathematical Operators: Intersection, Union, Difference, Symmetric Difference. Standard Set is mutable, Python has a immutable version called frozenset.Sets created by putting comma seperated values inside braces: school_bag = {'book','paper','pencil','pencil','book','book','book','eraser'} print(school_bag) Also can use set constructor to automatically put it into a set. letters = set('abracadabra') print(letters) #Built-In Functions #Functions using iterables filter(function, iterable) : creates new iterable of the same type which includes each item for which the function returns true. map(function, iterable) : creates new iterable of the same type which includes the result of calling the function on every item of the iterable. sorted(iterable, key=None, reverse=False) : creates a new sorted list from the items in the iterable. Output is always a list key: opt function which coverts and item to a value to be compared. reverse: optional boolean. enumerate(iterable, start=0) : starts with a sequence and converts it to a series of tuples quarters = ['First', 'Second', 'Third', 'Fourth'] print(enumerate(quarters)) print(enumerate(quarters, start=1)) (0, 'First'), (1, 'Second'), (2, 'Third'), (3, 'Fourth')(1, 'First'), (2, 'Second'), (3, 'Third'), (4, 'Fourth') zip(*iterables) : creates a zip object filled with tuples that combine 1 to 1 the items in each provided iterable.Functions that analyze iterable len(iterable) : returns the count of the number of items.* max(args, key=None) : returns the largest of two or more arguments. max(iterable, key=None) : returns the largest item in the iterable. key optional function which converts an item to a value to be compared.min works the same way as max sum(iterable) : used with a list of numbers to generate the total. There is a faster way to concatenate an array of strings into one string, so do not use sum for that. any(iterable) : returns True if any items in the iterable are true. all(iterable) : returns True is all items in the iterable are true. Working with dictionaries dir(dictionary) : returns the list of keys in the dictionary.Working with sets* Union : The pipe | operator or union(sets) function can be used to produce a new set which is a combination of all elements in the provided set. a = {1, 2, 3} b = {2, 4, 6} print(a | b) # => {1, 2, 3, 4, 6} Intersection : The & operator ca be used to produce a new set of only the elements that appear in all sets. a = {1, 2, 3} b = {2, 4, 6} print(a & b) # => {2} Difference : The — operator can be used to produce a new set of only the elements that appear in the first set and NOT the others. Symmetric Difference : The ^ operator can be used to produce a new set of only the elements that appear in exactly one set and not in both. a = {1, 2, 3} b = {2, 4, 6} print(a — b) # => {1, 3} print(b — a) # => {4, 6} print(a ^ b) # => {1, 3, 4, 6} For StatementsIn python, there is only one for loop. Always Includes: The for keyword2. A variable name3. The 'in' keyword4. An iterable of some kid5. A colon6. On the next line, an indented block of code called the for clause. You can use break and continue statements inside for loops as well. You can use the range function as the iterable for the for loop. print('My name is') for i in range(5): print('Carlita Cinco (' + str(i) + ')')total = 0 for num in range(101): total += num print(total) Looping over a list in Python for c in ['a', 'b', 'c']: print(c)lst = [0, 1, 2, 3] for i in lst: print(i) Common technique is to use the len() on a pre-defined list with a for loop to iterate over the indices of the list. supplies = ['pens', 'staplers', 'flame-throwers', 'binders'] for i in range(len(supplies)): print('Index ' + str(i) + ' in supplies is: ' + supplies[i]) **** You can loop and destructure at the same time. l = 1, 2], [3, 4], [5, 6 for a, b in l: print(a, ', ', b) Prints 1, 2Prints 3, 4Prints 5, 6 You can use values() and keys() to loop over dictionaries. spam = {'color': 'red', 'age': 42} for v in spam.values(): print(v) Prints red Prints 42 for k in spam.keys(): print(k) Prints color Prints age For loops can also iterate over both keys and values. Getting tuples for i in spam.items(): print(i) Prints ('color', 'red') Prints ('age', 42) Destructuring to values for k, v in spam.items(): print('Key: ' + k + ' Value: ' + str(v)) Prints Key: age Value: 42 Prints Key: color Value: red Looping over string for c in “abcdefg”: print(c) When you order arguments within a function or function call, the args need to occur in a particular order: formal positional args. args keyword args with default values*kwargs def example(arg_1, arg_2, *args, **kwargs): passdef example2(arg_1, arg_2, *args, kw_1=”shark”, kw_2=”blowfish”, **kwargs): pass Importing in Python Modules are similar to packages in Node.js Come in different types: Built-In, Third-Party, Custom. All loaded using import statements. Terms module : Python code in a separate file.package : Path to a directory that contains modules.init.py : Default file for a package.submodule : Another file in a module's folder.function : Function in a module. A module can be any file but it is usually created by placing a special file init.py into a folder. pic Try to avoid importing with wildcards in Python. Use multiple lines for clarity when importing. from urllib.request import ( HTTPDefaultErrorHandler as ErrorHandler, HTTPRedirectHandler as RedirectHandler, Request, pathname2url, url2pathname, urlopen, ) Watching Out for Python 2 Python 3 removed <> and only uses != format() was introduced with P3 All strings in P3 are unicode and encoded.md5 was removed. ConfigParser was renamed to configparsersets were killed in favor of set() class. print was a statement in P2, but is a function in P3. https://gist.github.com/bgoonz/82154f50603f73826c27377ebaa498b5#file-python-study-guide-py https://gist.github.com/bgoonz/282774d28326ff83d8b42ae77ab1fee3#file-python-cheatsheet-py https://gist.github.com/bgoonz/999163a278b987fe47fb247fd4d66904#file-python-cheat-sheet-md Built-in Functions
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    google-sheets-api If you're maintaining a dataset that frequently has to be updated in a predictable and consistent manner, automating that process has obvious benefits. It might cost some time to set up the code to automate the work, but you'll likely save time in the long run. And, if you're like me, writing the code will be less mind-numbing than repeatedly updating the same spreadsheet over and over again! Screenshot of Google Cloud Console edited by the author. taken after successfully running the quickstart script.. Screenshot by the author. Google spreadsheets provide excellent functionality for maintaining basic datasets. Some of the obvious advantages are that they are free, easy to access, and easy to share. Moreover, Google spreadsheets can be especially powerful because of their ability to connect with tools like Zapier or Phantombuster that can create automated workflows between a plethora of different online applications. Although these kinds of tools usually offer functionalities to automatically manipulate Google spreadsheets as well, I've experienced a lack of flexibility on how to update your spreadsheets. A customized Python script can offer way more flexibility and possibilities. To update your Google spreadsheets with Python, you can use the Google sheets API. Google offers free API access to several of their workspace apps, like Gmail, Google Calendar, Google Drive, and Google Sheets. You can check out their API library here. Below I'll walk you through the steps to set up the Google Sheets API with Python and show a couple of basic examples of how to manipulate spreadsheets using the API. Setting Up the API Step 1: Create a Google Cloud Platform project To get started with any of the Google workspace APIs, you need to have a so-called Google Cloud Platform (GCP) project. A GCP project forms the basis for all of Google's cloud computing services, including their API library. Setting up a project and using the APIs is completely free. Follow the steps outlined here to create your GCP project. It should be pretty straightforward. Step 2: Create Credentials After creating a GCP project (step 1), we need to set up our credentials for accessing the API. Our credentials are like a key for the API to know who is requesting access to its data and services. You can follow the steps listed here to create desktop application credentials. In my experience, some steps were missing in this tutorial, so I'm giving the detailed version below. Start by navigating back to your Google Cloud Console. Find the APIs & Services tab, and then select the Credentials page Click on *+Create Credentials *and select OAuth client ID. Select Desktop app as the application type and give your app a name. Then click create. You will be prompted to set up your OAuth consent screen. Follow the steps you are prompted with and make sure to add yourself as a test user. After generating your client ID, you will be able to see it on your credentials page. Click the download button to download a JSON file with your credentials. Rename it to credentials.json. You will need this in the next step. Step 3: Set up the API After creating a GCP project and generating your credentials, it is time to connect to the API with Python for the first time. You can follow the steps outlined here. The steps given on the Google developers page are pretty self-explanatory. Three things I want to add: Make sure to have a look at the prerequisites before diving in. Don't forget to move your credentials.json file to the same folder where your quickstart.py file is. Change the URL in the SCOPE list in the quickstart script to https://www.googleapis.com/auth/spreadsheets to make sure that you have both read and write access. If everything goes as expected, you should see this in your browser after running the sample script: After successfully running the sample, you will also find a token.json file in your workspace. This file is used for authentication on any of your future calls to the API. You're now ready to use the API! Using the API Now that we have set up the API connection, we can use the API to create, read, and edit Google spreadsheets! Extensive documentation on how to use the API can be found here. I'll run through a few basic examples below. Reading from an existing spreadsheet Reading from an existing spreadsheet is a key functionality if you want to automate your spreadsheets. Let's create a new spreadsheet in the Google workspace and input some data. Below is a screenshot of the table I created. The API identifies spreadsheets using a spreadsheet ID. To connect to a spreadsheet that already exists, you can find the spreadsheet ID in the Google Sheets URL as follows: After identifying the spreadsheet ID of the spreadsheet we just created, we can use the API to connect to the spreadsheet and to read its data. Below is a code example of how to do this. The main functionalities to retrieve data from an existing spreadsheet are provided by sheet.values().get().execute()* on line 17. *Note that this is where we pass the spreadsheet ID and the range of values in the sheet we want to retrieve. All code before that establishes the connection to the API and is very similar to the quickstart.py file we used to connect to the API for the first time. The code returns a list of lists containing the data of our spreadsheet. Note that the data is returned row-by-row this way. Writing to an existing spreadsheet Next, let's try to add a new value to the spreadsheet. After all, this is the second key bit we need to automatically update our spreadsheets. The code below shows how to add a row to the existing data with the values [6, f]. Similar to reading values from an existing sheet, we need to start with establishing the connection to the API and identifying the spreadsheet ID. Because we are now writing new data to the spreadsheet, it is essential to make sure that you have not specified read-only permission in your SCOPES list (line 5). The main functionalities to append new data to an existing spreadsheet are provided by *sheet.values().append().execute() on lines 17–22. *Note that this is where we pass the spreadsheet ID, spreadsheet range, and several other parameters that specify how the data has to be inserted and what data has to be inserted. The body parameter takes a dictionary with values to append to the existing data table, using the same list-of-list format we saw before. After running the code, the spreadsheet is automatically updated with our new entry. The new row is neatly appended to the data that we manually wrote in the spreadsheet. Final Thoughts The Google workspace API library is a really powerful and relatively user-friendly way to automate workflows related to any of the Google workspace applications. In this tutorial, I walked you through setting up the Google Sheets API with Python and showed a few examples of how to manipulate spreadsheets using this API. The possibilities of how to use this are endless. Setting up access to the other APIs involves a very similar process and would allow for even more elaborate and complex automation flows.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Functions def hello(name): print('Hello {}'.format(name)) Return Values and return Statements When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following: The return keyword. The value or expression that the function should return. import random def getAnswer(answerNumber): if answerNumber == 1: return 'It is certain' elif answerNumber == 2: return 'It is decidedly so' elif answerNumber == 3: return 'Yes' elif answerNumber == 4: return 'Reply hazy try again' elif answerNumber == 5: return 'Ask again later' elif answerNumber == 6: return 'Concentrate and ask again' elif answerNumber == 7: return 'My reply is no' elif answerNumber == 8: return 'Outlook not so good' elif answerNumber == 9: return 'Very doubtful' r = random.randint(1, 9) fortune = getAnswer(r) print(fortune) The None Value spam = print('Hello!') spam is None Note: never compare to None with the == operator. Always use is. print Keyword Arguments print('Hello', end='') print('World') print('cats', 'dogs', 'mice') print('cats', 'dogs', 'mice', sep=',') Local and Global Scope Code in the global scope cannot use any local variables. However, a local scope can access global variables. Code in a function's local scope cannot use variables in any other local scope. You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam. The global Statement If you need to modify a global variable from within a function, use the global statement: def spam(): global eggs eggs = 'spam' eggs = 'global' spam() print(eggs) There are four rules to tell whether a variable is in a local scope or global scope: If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable. If there is a global statement for that variable in a function, it is a global variable. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable. But if the variable is not used in an assignment statement, it is a global variable.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Flow Control: Read It Website Github PDF Jupyter Notebook Flow Control Comparison Operators Operator Meaning== Equal to!= Not equal to< Less than> Greater Than<= Less than or Equal to>= Greater than or Equal to These operators evaluate to True or False depending on the values you give them. Examples: 42 == 42 40 == 42 'hello' == 'hello' 'hello' == 'Hello' 'dog' != 'cat' 42 == 42.0 42 == '42' Boolean evaluation Never use == or != operator to evaluate boolean operation. Use the is or is not operators, or use implicit boolean evaluation. NO (even if they are valid Python): True == True True != False YES (even if they are valid Python): True is True True is not False These statements are equivalent: if a is True: pass if a is not False: pass if a: pass And these as well: if a is False: pass if a is not True: pass if not a: pass Boolean Operators There are three Boolean operators: and, or, and not. The and Operator's Truth Table: Expression Evaluates to True and True True True and False False False and True False False and False False The or Operator's Truth Table: Expression Evaluates to True or True True True or False True False or True True False or False False The not Operator's Truth Table: Expression Evaluates to not True False not False True Mixing Boolean and Comparison Operators(4 < 5) and (5 < 6) (4 < 5) and (9 < 6) (1 == 2) or (2 == 2) You can also use multiple Boolean operators in an expression, along with the comparison operators: 2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2 if Statements if name == 'Alice': print('Hi, Alice.') else Statements name = 'Bob' if name == 'Alice': print('Hi, Alice.') else: print('Hello, stranger.') elif Statements name = 'Bob' age = 5 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') name = 'Bob' age = 30 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') else: print('You are neither Alice nor a little kid.') while Loop Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 break Statements If the execution reaches a break statement, it immediately exits the while loop's clause: while True: print('Please type your name.') name = input() if name == 'your name': break print('Thank you!') continue Statements When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop. while True: print('Who are you?') name = input() if name != 'Joe': continue print('Hello, Joe. What is the password? (It is a fish.)') password = input() if password == 'swordfish': break print('Access granted.') for Loops and the range() Function print('My name is') for i in range(5): print('Jimmy Five Times ({})'.format(str(i))) The range() function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration. for i in range(0, 10, 2): print(i) You can even use a negative number for the step argument to make the for loop count down instead of up. for i in range(5, -1, -1): print(i) For else statement This allows you to specify a statement to execute after the full loop has been executed. Only useful when a break condition can occur in the loop: for i in [1, 2, 3, 4, 5]: if i == 3: break else: print("only executed when no item of the list is equal to 3") Importing Modules import random for i in range(5): print(random.randint(1, 10)) import random, sys, os, math from random import * Ending a Program with sys.exit import sys while True: print('Type exit to exit.') response = input() if response == 'exit': sys.exit() print('You typed {}.'.format(response))
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Practice Python Practice: Python Problems & Solutions For Beginners Introduction to python taught through example problems. Solutions are included in embedded repl.it at the bottom of this page for you to… Python Problems & Solutions For Beginners Introduction to python taught through example problems. Solutions are included in embedded repl.it at the bottom of this page for you to practice and refactor. Python Practice Problems Here are some other articles for reference if you need them: Beginners Guide To Python My favorite language for maintainability is Python. It has simple, clean syntax, object encapsulation, good library… medium.com Python Study Guide for a JavaScript Programmer A guide to commands in Python from what you know in JavaScript levelup.gitconnected.com Here are the problems without solutions for you to practice with: Problem 1 Create a program that asks the user to enter their name and their age. Print out a message addressed to them that tells them the year that they will turn 100 years old. The datetime module supplies classes for manipulating dates and times. While date and time arithmetic is supported, the focus of the implementation is on efficient attribute extraction for output formatting and manipulation. datetime - Basic date and time types - Python 3.9.6 documentation Only one concrete class, the class, is supplied by the module. The class can represent simple timezones with fixed… docs.python.org Problem 2 Ask the user for a number. Depending on whether the number is even or odd, print out an appropriate message to the user. Bonus: If the number is a multiple of 4, print out a different message. Ask the user for two numbers: one number to check (call it num) and one number to divide by (check). If check divides evenly into num, tell that to the user. If not, print a different appropriate message. Problem 3 Take a list and write a program that prints out all the elements of the list that are less than 5. Extras: Instead of printing the elements one by one, make a new list that has all the elements less than 5 from this list in it and print out this new list. Write this in one line of Python. Ask the user for a number and return a list that contains only elements from the original list a that are smaller than that number given by the user. Problem 4 Create a program that asks the user for a number and then prints out a list of all the divisors of that number. (If you don't know what a divisor is, it is a number that divides evenly into another number. For example, 13 is a divisor of 26 because 26 / 13 has no remainder.) Problem 5 Take two lists, and write a program that returns a list that contains only the elements that are common between the lists (without duplicates). Make sure your program works on two lists of different sizes. random - Generate pseudo-random numbers - Python 3.9.6 documentation Source code: Lib/random.py This module implements pseudo-random number generators for various distributions. For… docs.python.org Bonus: Randomly generate two lists to test this. Write this in one line of Python. Problem 6 Ask the user for a string and print out whether this string is a palindrome or not. (A palindrome is a string that reads the same forwards and backwards.) Here's 5 ways to reverse a string (courtesy of geeksforgeeks) Problem 7 Let's say I give you a list saved in a variable: a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]. Write one line of Python that takes this list a and makes a new list that has only the even elements of this list in it. Problem 8 Make a two-player Rock-Paper-Scissors game. Hint: Ask for player plays (using input), compare them. Print out a message of congratulations to the winner, and ask if the players want to start a new game.### Problem 9 Generate a random number between 1 and 100 (including 1 and 100). Ask the user to guess the number, then tell them whether they guessed too low, too high, or exactly right. Hint: Remember to use the user input from the very first exercise. Extras: Keep the game going until the user types “exit”. Keep track of how many guesses the user has taken, and when the game ends, print this out. Problem 10 Write a program that asks the user how many Fibonacci numbers to generate and then generates them. Take this opportunity to think about how you can use functions. Make sure to ask the user to enter the number of numbers in the sequence to generate. Hint: The Fibonacci sequence is a sequence of numbers where the next number in the sequence is the sum of the previous two numbers in the sequence. The sequence looks like this: 1, 1, 2, 3, 5, 8, 13, … Intermediate Problems: Problem 11 In linear algebra, a Toeplitz matrix is one in which the elements on any given diagonal from top left to bottom right are identical. Here is an example: 1 2 3 4 8 5 1 2 3 4 4 5 1 2 3 7 4 5 1 2 Write a program to determine whether a given input is a Toeplitz matrix. Problem 12 Given a positive integer N, find the smallest number of steps it will take to reach 1. There are two kinds of permitted steps: — -> You may decrement N to N — 1. — -> If a * b = N, you may decrement N to the larger of a and b. For example, given 100, you can reach 1 in 5 steps with the following route: 100 -> 10 -> 9 -> 3 -> 2 -> 1. Problem 13 Consider the following scenario: there are N mice and N holes placed at integer points along a line. Given this, find a method that maps mice to holes such that the largest number of steps any mouse takes is minimized. Each move consists of moving one mouse one unit to the left or right, and only one mouse can fit inside each hole. For example, suppose the mice are positioned at [1, 4, 9, 15], and the holes are located at [10, -5, 0, 16]. In this case, the best pairing would require us to send the mouse at 1 to the hole at -5, so our function should return 6. My Blog: Web-Dev-Hub Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of… master--bgoonz-blog.netlify.app A list of all of my articles to link to future posts You should probably skip this one… seriously it's just for internal use! bryanguner.medium.com Python Python is an interpreted, high-level and general-purpose, dynamically typed programming language It is also Object oriented, modular oriented and a scripting language. In Python, everything is considered as an Object. A python file has an extension of .py Python follows Indentation to separate code blocks instead of flower brackets({}). We can run a python file by the following command in cmd(Windows) or shell(mac/linux). python <filename.py> By default, the python doesn't require any imports to run a python file. Create and execute a program Open up a terminal/cmd Create the program: nano/cat > nameProgram.py Write the program and save it python nameProgram.py Basic Datatypes Data Type Description int Integer values [0, 1, -2, 3] float Floating point values [0.1, 4.532, -5.092] char Characters [a, b, @, !, `] str Strings [abc, AbC, A@B, sd!, `asa] bool Boolean Values [True, False] char Characters [a, b, @, !, `] complex Complex numbers [2+3j, 4-1j] Keywords Keyword Description break used to exit loop and used to exit char basic declaration of a type character const prefix declaration meaning variable can not be changed continue go to bottom of loop in for, while loops class to define a class def to define a function elif shortcut for (else if) used in else if ladder else executable statement, part of "if" structure float basic declaration of floating point for executable statement, for loop from executable statement, used to import only specific objects from a package if executable statement import to import modules pass keyword to specify noting is happening in the codeblock, generally used in classes return executable statement with or without a value while executable statement, while loop Operators Operator Description( ) grouping parenthesis, function call, tuple declaration[ ] array indexing, also declaring lists etc.! relational not, complement, ! a yields true or false~ bitwise not, ones complement, ~a- unary minus, - a+ unary plus, + a* multiply, a * b/ divide, a / b% modulo, a % b+ add, a + b- subtract, a - b<< shift left, left operand is shifted left by right operand bits>> shift right, left operand is shifted right by right operand bits< less than, result is true or false, a %lt; b<= less than or equal, result is true or false, a <= b> greater than, result is true or false, a > b>= greater than or equal, result is true or false, a >= b== equal, result is true or false, a == b!= not equal, result is true or false, a != b& bitwise and, a & b^ bitwise exclusive or XOR, a ^ b| bitwise or, a b&&, and relational and, result is true or false, a < b && c >= d||, or relational or, result is true or false, a < b || c >= d= store or assignment+= add and store-= subtract and store*= multiply and store/= divide and store%= modulo and store<<= shift left and store>>= shift right and store&= bitwise and and store^= bitwise exclusive or and store|= bitwise or and store, separator as in ( y=x,z=++x ) Basic Data Structures List List is a collection which is ordered and changeable. Allows duplicate members. Lists are created using square brackets: thislist = ["apple", "banana", "cherry"] List items are ordered, changeable, and allow duplicate values. List items are indexed, the first item has index [0], the second item has index [1] etc. The list is changeable, meaning that we can change, add, and remove items in a list after it has been created. To determine how many items a list has, use the len() function. A list can contain different data types: list1 = ["abc", 34, True, 40, "male"] It is also possible to use the list() constructor when creating a new list thislist = list(("apple", "banana", "cherry")) # note the double round-brackets Tuple Tuple is a collection which is ordered and unchangeable. Allows duplicate members. A tuple is a collection which is ordered and unchangeable. Tuples are written with round brackets. thistuple = ("apple", "banana", "cherry") Tuple items are ordered, unchangeable, and allow duplicate values. Tuple items are indexed, the first item has index [0], the second item has index [1] etc. When we say that tuples are ordered, it means that the items have a defined order, and that order will not change. Tuples are unchangeable, meaning that we cannot change, add or remove items after the tuple has been created. Since tuple are indexed, tuples can have items with the same value: Tuples allow duplicate values: thistuple = ("apple", "banana", "cherry", "apple", "cherry") To determine how many items a tuple has, use the len() function: thistuple = ("apple", "banana", "cherry") print(len(thistuple)) To create a tuple with only one item, you have to add a comma after the item, otherwise Python will not recognize it as a tuple. thistuple = ("apple",) print(type(thistuple)) #NOT a tuple thistuple = ("apple") print(type(thistuple)) It is also possible to use the tuple() constructor to make a tuple. thistuple = tuple(("apple", "banana", "cherry")) # note the double round-brackets print(thistuple) Set Set is a collection which is unordered and unindexed. No duplicate members. A set is a collection which is both unordered and unindexed. thisset = {"apple", "banana", "cherry"} Set items are unordered, unchangeable, and do not allow duplicate values. Unordered means that the items in a set do not have a defined order. Set items can appear in a different order every time you use them, and cannot be referred to by index or key. Sets are unchangeable, meaning that we cannot change the items after the set has been created. Duplicate values will be ignored. To determine how many items a set has, use the len() method. thisset = {"apple", "banana", "cherry"} print(len(thisset)) Set items can be of any data type: set1 = {"apple", "banana", "cherry"} set2 = {1, 5, 7, 9, 3} set3 = {True, False, False} set4 = {"abc", 34, True, 40, "male"} It is also possible to use the set() constructor to make a set. thisset = set(("apple", "banana", "cherry")) # note the double round-brackets Dictionary Dictionary is a collection which is unordered and changeable. No duplicate members. Dictionaries are used to store data values in key:value pairs. Dictionaries are written with curly brackets, and have keys and values: thisdict = { "brand": "Ford", "model": "Mustang", "year": 1964 } Dictionary items are presented in key:value pairs, and can be referred to by using the key name. thisdict = { "brand": "Ford", "model": "Mustang", "year": 1964 } print(thisdict["brand"]) Dictionaries are changeable, meaning that we can change, add or remove items after the dictionary has been created. Dictionaries cannot have two items with the same key. Duplicate values will overwrite existing values. To determine how many items a dictionary has, use the len() function. print(len(thisdict)) The values in dictionary items can be of any data type thisdict = { "brand": "Ford", "electric": False, "year": 1964, "colors": ["red", "white", "blue"] } Conditional branching if condition: pass elif condition2: pass else: pass Loops Python has two primitive loop commands: while loops for loops While loop With the while loop we can execute a set of statements as long as a condition is true. Example: Print i as long as i is less than 6 i = 1 while i < 6: print(i) i += 1 The while loop requires relevant variables to be ready, in this example we need to define an indexing variable, i, which we set to 1. With the break statement we can stop the loop even if the while condition is true With the continue statement we can stop the current iteration, and continue with the next. With the else statement we can run a block of code once when the condition no longer is true. For loop A for loop is used for iterating over a sequence (that is either a list, a tuple, a dictionary, a set, or a string). This is less like the for keyword in other programming languages, and works more like an iterator method as found in other object-orientated programming languages. With the for loop we can execute a set of statements, once for each item in a list, tuple, set etc. fruits = ["apple", "banana", "cherry"] for x in fruits: print(x) The for loop does not require an indexing variable to set beforehand. To loop through a set of code a specified number of times, we can use the range() function. The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number. The range() function defaults to increment the sequence by 1, however it is possible to specify the increment value by adding a third parameter: range(2, 30, 3). The else keyword in a for loop specifies a block of code to be executed when the loop is finished. A nested loop is a loop inside a loop. The "inner loop" will be executed one time for each iteration of the "outer loop": adj = ["red", "big", "tasty"] fruits = ["apple", "banana", "cherry"] for x in adj: for y in fruits: print(x, y) for loops cannot be empty, but if you for some reason have a for loop with no content, put in the pass statement to avoid getting an error. for x in [0, 1, 2]: pass Function definition def function_name(): return Function call function_name() We need not to specify the return type of the function. Functions by default return None We can return any datatype. def say_hi(name): """<---- Multi-Line Comments and Docstrings This is where you put your content for help() to inform the user about what your function does and how to use it """ print(f"Hello {name}!") print(say_hi("Bryan")) # Should get the print inside the function, then None # Boolean Values # Work the same as in JS, except they are title case: True and False a = True b = False # Logical Operators # ! = not, || = or, && = and print(True and True) print(True and not True) print(True or True) # Truthiness - Everything is True except... # False - None, False, '', [], (), set(), range(0) # Number Values # Integers are numbers without a floating decimal point print(type(3)) # type returns the type of whatever argument you pass in # Floating Point values are numbers with a floating decimal point print(type(3.5)) # Type Casting # You can convert between ints and floats (along with other types...) print(float(3)) # If you convert a float to an int, it will truncate the decimal print(int(4.5)) print(type(str(3))) # Python does not automatically convert types like JS # print(17.0 + ' heyooo ' + 17) # TypeError # Arithmetic Operators # ** - exponent (comparable to Math.pow(num, pow)) # // - integer division # There is no ++ or -- in Python # String Values # We can use single quotes, double quotes, or f'' for string formats # We can use triple single quotes for multiline strings print( """This here's a story All about how My life got twist Turned upside down """ ) # Three double quotes can also be used, but we typically reserve these for # multi-line comments and function docstrings (refer to lines 6-9)(Nice :D) # We use len() to get the length of something print(len("Bryan G")) # 7 characters print(len(["hey", "ho", "hey", "hey", "ho"])) # 5 list items print(len({1, 2, 3, 4, 5, 6, 7, 9})) # 8 set items # We can index into strings, list, etc..self. name = "Bryan" for i in range(len(name)): print(name[i]) # B, r, y, a, n # We can index starting from the end as well, with negatives occupation = "Full Stack Software Engineer" print(occupation[-3]) # e # We can also get ranges in the index with the [start:stop:step] syntax print(occupation[0:4:1]) # step and stop are optional, stop is exclusive print(occupation[::4]) # beginning to end, every 4th letter print(occupation[4:14:2]) # Let's get weird with it! # NOTE: Indexing out of range will give you an IndexError # We can also get the index og things with the .index() method, similar to indexOf() print(occupation.index("Stack")) print(["Mike", "Barry", "Cole", "James", "Mark"].index("Cole")) # We can count how many times a substring/item appears in something as well print(occupation.count("S")) print( """Now this here's a story all about how My life got twist turned upside down I forget the rest but the the the potato smells like the potato""".count( "the" ) ) # We concatenate the same as Javascript, but we can also multiply strings print("dog " + "show") print("ha" * 10) # We can use format for a multitude of things, from spaces to decimal places first_name = "Bryan" last_name = "Guner" print("Your name is {0} {1}".format(first_name, last_name)) # Useful String Methods print("Hello".upper()) # HELLO print("Hello".lower()) # hello print("HELLO".islower()) # False print("HELLO".isupper()) # True print("Hello".startswith("he")) # False print("Hello".endswith("lo")) # True print("Hello There".split()) # [Hello, There] print("hello1".isalpha()) # False, must consist only of letters print("hello1".isalnum()) # True, must consist of only letters and numbers print("3215235123".isdecimal()) # True, must be all numbers # True, must consist of only spaces/tabs/newlines print(" \n ".isspace()) # False, index 0 must be upper case and the rest lower print("Bryan Guner".istitle()) print("Michael Lee".istitle()) # True! # Duck Typing - If it walks like a duck, and talks like a duck, it must be a duck # Assignment - All like JS, but there are no special keywords like let or const a = 3 b = a c = "heyoo" b = ["reassignment", "is", "fine", "G!"] # Comparison Operators - Python uses the same equality operators as JS, but no === # < - Less than # > - Greater than # <= - Less than or Equal # >= - Greater than or Equal # == - Equal to # != - Not equal to # is - Refers to exact same memory location # not - ! # Precedence - Negative Signs(not) are applied first(part of each number) # - Multiplication and Division(and) happen next # - Addition and Subtraction(or) are the last step # NOTE: Be careful when using not along with == print(not a == b) # True # print(a == not b) # Syntax Error print(a == (not b)) # This fixes it. Answer: False # Python does short-circuit evaluation # Assignment Operators - Mostly the same as JS except Python has **= and //= (int division) # Flow Control Statements - if, while, for # Note: Python smushes 'else if' into 'elif'! if 10 < 1: print("We don't get here") elif 10 < 5: print("Nor here...") else: print("Hey there!") # Looping over a string for c in "abcdefgh": print(c) # Looping over a range for i in range(5): print(i + 1) # Looping over a list lst = [1, 2, 3, 4] for i in lst: print(i) # Looping over a dictionary spam = {"color": "red", "age": 42, "items": [(1, "hey"), (2, "hooo!")]} for v in spam.values(): print(v) # Loop over a list of tuples and destructuring the values # Assuming spam.items returns a list of tuples each containing two items (k, v) for k, v in spam.items(): print(f"{k}: {v}") # While loops as long as the condition is True # - Exit loop early with break # - Exit iteration early with continue spam = 0 while True: print("Sike That's the wrong Numba") spam += 1 if spam < 5: continue break # Functions - use def keyword to define a function in Python def printCopyright(): print("Copyright 2021, Bgoonz") # Lambdas are one liners! (Should be at least, you can use parenthesis to disobey) avg = lambda num1, num2: print(num1 + num2) avg(1, 2) # Calling it with keyword arguments, order does not matter avg(num2=20, num1=1252) printCopyright() # We can give parameters default arguments like JS def greeting(name, saying="Hello"): print(saying, name) greeting("Mike") # Hello Mike greeting("Bryan", saying="Hello there...") # A common gotcha is using a mutable object for a default parameter # All invocations of the function reference the same mutable object def append_item(item_name, item_list=[]): # Will it obey and give us a new list? item_list.append(item_name) return item_list # Uses same item list unless otherwise stated which is counterintuitive print(append_item("notebook")) print(append_item("notebook")) print(append_item("notebook", [])) # Errors - Unlike JS, if we pass the incorrect amount of arguments to a function, # it will throw an error # avg(1) # TypeError # avg(1, 2, 2) # TypeError # ----------------------------------- DAY 2 ---------------------------------------- # Functions - * to get rest of position arguments as tuple # - ** to get rest of keyword arguments as a dictionary # Variable Length positional arguments def add(a, b, *args): # args is a tuple of the rest of the arguments total = a + b for n in args: total += n return total print(add(1, 2)) # args is None, returns 3 print(add(1, 2, 3, 4, 5, 6)) # args is (3, 4, 5, 6), returns 21 # Variable Length Keyword Arguments def print_names_and_countries(greeting, **kwargs): # kwargs is a dictionary of the rest of the keyword arguments for k, v in kwargs.items(): print(greeting, k, "from", v) print_names_and_countries( "Hey there", Monica="Sweden", Mike="The United States", Mark="China" ) # We can combine all of these together def example2(arg1, arg2, *args, kw_1="cheese", kw_2="horse", **kwargs): pass # Lists are mutable arrays empty_list = [] roomates = ["Beau", "Delynn"] # List built-in function makes a list too specials = list() # We can use 'in' to test if something is in the list, like 'includes' in JS print(1 in [1, 2, 4]) # True print(2 in [1, 3, 5]) # False # Dictionaries - Similar to JS POJO's or Map, containing key value pairs a = {"one": 1, "two": 2, "three": 3} b = dict(one=1, two=2, three=3) # Can use 'in' on dictionaries too (for keys) print("one" in a) # True print(3 in b) # False # Sets - Just like JS, unordered collection of distinct objects bedroom = {"bed", "tv", "computer", "clothes", "playstation 4"} # bedroom = set("bed", "tv", "computer", "clothes", "playstation 5") school_bag = set( ["book", "paper", "pencil", "pencil", "book", "book", "book", "eraser"] ) print(school_bag) print(bedroom) # We can use 'in' on sets as wel print(1 in {1, 2, 3}) # True print(4 in {1, 3, 5}) # False # Tuples are immutable lists of items time_blocks = ("AM", "PM") colors = "red", "green", "blue" # Parenthesis not needed but encouraged # The tuple built-in function can be used to convert things to tuples print(tuple("abc")) print(tuple([1, 2, 3])) # 'in' may be used on tuples as well print(1 in (1, 2, 3)) # True print(5 in (1, 4, 3)) # False # Ranges are immutable lists of numbers, often used with for loops # - start - default: 0, first number in sequence # - stop - required, next number past last number in sequence # - step - default: 1, difference between each number in sequence range1 = range(5) # [0,1,2,3,4] range2 = range(1, 5) # [1,2,3,4] range3 = range(0, 25, 5) # [0,5,10,15,20] range4 = range(0) # [] for i in range1: print(i) # Built-in functions: # Filter isOdd = lambda num: num % 2 == 1 filtered = filter(isOdd, [1, 2, 3, 4]) print(list(filtered)) for num in filtered: print(f"first way: {num}") print("--" * 20) [print(f"list comprehension: {i}") for i in [1, 2, 3, 4, 5, 6, 7, 8] if i % 2 == 1] # Map def toUpper(str): return str.upper() upperCased = map(toUpper, ["a", "b", "c", "d"]) print(list(upperCased)) # Sorted sorted_items = sorted(["john", "tom", "sonny", "Mike"]) print(list(sorted_items)) # Notice uppercase comes before lowercase # Using a key function to control the sorting and make it case insensitive sorted_items = sorted(["john", "tom", "sonny", "Mike"], key=str.lower) print(sorted_items) # You can also reverse the sort sorted_items = sorted(["john", "tom", "sonny", "Mike"], key=str.lower, reverse=True) print(sorted_items) # Enumerate creates a tuple with an index for what you're enumerating quarters = ["First", "Second", "Third", "Fourth"] print(list(enumerate(quarters))) print(list(enumerate(quarters, start=1))) # Zip takes list and combines them as key value pairs, or really however you need keys = ("Name", "Email") values = ("Buster", "cheetoh@johhnydepp.com") zipped = zip(keys, values) print(list(zipped)) # You can zip more than 2 x_coords = [0, 1, 2, 3, 4] y_coords = [4, 6, 10, 9, 10] z_coords = [20, 10, 5, 9, 1] coords = zip(x_coords, y_coords, z_coords) print(list(coords)) # Len reports the length of strings along with list and any other object data type print_len = lambda item: print(len(item)) # doing this to save myself some typing print_len("Mike") print_len([1, 5, 2, 10, 3, 10]) print_len({1, 5, 10, 9, 10}) # 4 because there is a duplicate here (10) print_len((1, 4, 10, 9, 20)) # Max will return the max number in a given scenario print(max(1, 2, 35, 1012, 1)) # Min print(min(1, 5, 2, 10)) print(min([1, 4, 7, 10])) # Sum print(sum([1, 2, 4])) # Any print(any([True, False, False])) print(any([False, False, False])) # All print(all([True, True, False])) print(all([True, True, True])) # Dir returns all the attributes of an object including it's methods and dunder methods user = {"Name": "Bob", "Email": "bob@bob.com"} print(dir(user)) # Importing packages and modules # - Module - A Python code in a file or directory # - Package - A module which is a directory containing an __init__.py file # - Submodule - A module which is contained within a package # - Name - An exported function, class, or variable in a module # Unlike JS, modules export ALL names contained within them without any special export key # Assuming we have the following package with four submodules # math # | __init__.py # | addition.py # | subtraction.py # | multiplication.py # | division.py # If we peek into the addition.py file we see there's an add function # addition.py # We can import 'add' from other places because it's a 'name' and is automatically exported def add(num1, num2): return num1 + num2 # Notice the . syntax because this package can import it's own submodules. # Our __init__.py has the following files # This imports the 'add' function # And now it's also re-exported in here as well # from .addition import add # These import and re-export the rest of the functions from the submodule # from .subtraction import subtract # from .division import divide # from .multiplication import multiply # So if we have a script.py and want to import add, we could do it many ways # This will load and execute the 'math/__init__.py' file and give # us an object with the exported names in 'math/__init__.py' import math # print(math.add(1,2)) # This imports JUST the add from 'math/__init__.py' # from math import add # print(add(1, 2)) # This skips importing from 'math/__init__.py' (although it still runs) # and imports directly from the addition.py file # from math.addition import add # This imports all the functions individually from 'math/__init__.py' # from math import add, subtract, multiply, divide # print(add(1, 2)) # print(subtract(2, 1)) # This imports 'add' renames it to 'add_some_numbers' # from math import add as add_some_numbers # --------------------------------------- DAY 3 --------------------------------------- # Classes, Methods, and Properties class AngryBird: # Slots optimize property access and memory usage and prevent you # from arbitrarily assigning new properties the instance __slots__ = ["_x", "_y"] # Constructor def __init__(self, x=0, y=0): # Doc String """ Construct a new AngryBird by setting it's position to (0, 0) """ ## Instance Variables self._x = x self._y = y # Instance Method def move_up_by(self, delta): self._y += delta # Getter @property def x(self): return self._x # Setter @x.setter def x(self, value): if value < 0: value = 0 self._x = value @property def y(self): return self._y @y.setter def y(self, value): self._y = value # Dunder Repr... called by 'print' def __repr__(self): return f"<AngryBird ({self._x}, {self._y})>" # JS to Python Classes cheat table # JS Python # constructor() def __init__(self): # super() super().__init__() # this.property self.property # this.method self.method() # method(arg1, arg2){} def method(self, arg1, ...) # get someProperty(){} @property # set someProperty(){} @someProperty.setter # List Comprehensions are a way to transform a list from one format to another # - Pythonic Alternative to using map or filter # - Syntax of a list comprehension # - new_list = [value loop condition] # Using a for loop squares = [] for i in range(10): squares.append(i ** 2) print(squares) # value = i ** 2 # loop = for i in range(10) squares = [i ** 2 for i in range(10)] print(list(squares)) sentence = "the rocket came back from mars" vowels = [character for character in sentence if character in "aeiou"] print(vowels) # You can also use them on dictionaries. We can use the items() method # for the dictionary to loop through it getting the keys and values out at once person = {"name": "Corina", "age": 32, "height": 1.4} # This loops through and capitalizes the first letter of all keys newPerson = {key.title(): value for key, value in person.items()} print(list(newPerson.items()))
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Comprehensive Python Guide About Contribute Read It Python Cheatsheet The Zen of Python Python Basics Math Operators Data Types String Concatenation and Replication Variables Comments The print() Function The input() Function The len() Function The str(), int(), and float() Functions Flow Control Comparison Operators Boolean evaluation Boolean Operators Mixing Boolean and Comparison Operators if Statements else Statements elif Statements while Loop Statements break Statements continue Statements for Loops and the range() Function For else statement Importing Modules Ending a Program Early with sys.exit() Functions Return Values and return Statements The None Value Keyword Arguments and print() Local and Global Scope The global Statement Exception Handling Basic exception handling Final code in exception handling Lists Getting Individual Values in a List with Indexes Negative Indexes Getting Sublists with Slices Getting a List's Length with len() Changing Values in a List with Indexes List Concatenation and List Replication Removing Values from Lists with del Statements Using for Loops with Lists Looping Through Multiple Lists with zip() The in and not in Operators The Multiple Assignment Trick Augmented Assignment Operators Finding a Value in a List with the index() Method Adding Values to Lists with the append() and insert() Methods Removing Values from Lists with remove() Removing Values from Lists with pop() Sorting the Values in a List with the sort() Method Tuple Data Type Converting Types with the list() and tuple() Functions Dictionaries and Structuring Data The keys(), values(), and items() Methods Checking Whether a Key or Value Exists in a Dictionary The get() Method The setdefault() Method Pretty Printing Merge two dictionaries sets Initializing a set sets: unordered collections of unique elements set add() and update() set remove() and discard() set union() set intersection set difference set symetric_difference itertools Module accumulate() combinations() combinations with replacement() count() cycle() chain() compress() dropwhile() filterfalse() groupby() islice() permutations() product() repeat() starmap() takewhile() tee() zip_longest() Comprehensions List comprehension Set comprehension Dict comprehension Manipulating Strings Escape Characters Raw Strings Multiline Strings with Triple Quotes Indexing and Slicing Strings The in and not in Operators with Strings The in and not in Operators with list The upper(), lower(), isupper(), and islower() String Methods The isX String Methods The startswith() and endswith() String Methods The join() and split() String Methods Justifying Text with rjust(), ljust(), and center() Removing Whitespace with strip(), rstrip(), and lstrip() Copying and Pasting Strings with the pyperclip Module (need pip install) String Formatting% operator String Formatting (str.format) Lazy string formatting Formatted String Literals or f-strings (Python 3.6+) Template Strings Regular Expressions Matching Regex Objects Grouping with Parentheses Matching Multiple Groups with the Pipe Optional Matching with the Question Mark Matching Zero or More with the Star Matching One or More with the Plus Matching Specific Repetitions with Curly Brackets Greedy and Nongreedy Matching The findall() Method Making Your Own Character Classes The Caret and Dollar Sign Characters The Wildcard Character Matching Everything with Dot-Star Matching Newlines with the Dot Character Review of Regex Symbols Case-Insensitive Matching Substituting Strings with the sub() Method Managing Complex Regexes Handling File and Directory Paths Backslash on Windows and Forward Slash on OS X and Linux The Current Working Directory Creating New Folders Absolute vs. Relative Paths Handling Absolute and Relative Paths Checking Path Validity Finding File Sizes and Folder Contents Copying Files and Folders Moving and Renaming Files and Folders Permanently Deleting Files and Folders Safe Deletes with the send2trash Module Walking a Directory Tree Reading and Writing Files The File Reading/Writing Process Opening and reading files with the open() function Writing to Files Saving Variables with the shelve Module Saving Variables with the pprint.pformat() Function Reading ZIP Files Extracting from ZIP Files Creating and Adding to ZIP Files JSON, YAML and configuration files JSON YAML Anyconfig Debugging Raising Exceptions Getting the Traceback as a String Assertions Logging Logging Levels Disabling Logging Logging to a File Lambda Functions Ternary Conditional Operator args and kwargs Things to Remember(args) Things to Remember(kwargs) Context Manager with statement Writing your own contextmanager using generator syntax __main__ Top-level script environment Advantages setup.py Dataclasses Features Default values Type hints Virtual Environment virtualenv poetry pipenv anaconda The Zen of Python From the PEP 20 -- The Zen of Python: Long time Pythoneer Tim Peters succinctly channels the BDFL's guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down.>>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! Return to the Top Python Basics Math Operators From Highest to Lowest precedence: Operators Operation Example** Exponent 2 ** 3 = 8% Modulus/Remainder 22 % 8 = 6// Integer division 22 // 8 = 2/ Division 22 / 8 = 2.75* Multiplication 3 * 3 = 9- Subtraction 5 - 2 = 3+ Addition 2 + 2 = 4 Examples of expressions in the interactive shell:>>> 2 + 3 * 6 20 >>> (2 + 3) * 6 30 >>> 2 ** 8 256 >>> 23 // 7 3 >>> 23 % 7 2 >>> (5 - 1) * ((7 + 1) / (3 - 1)) 16.0 Return to the Top Data Types Data Type Examples Integers-2, -1, 0, 1, 2, 3, 4, 5 Floating-point numbers-1.25, -1.0, --0.5, 0.0, 0.5, 1.0, 1.25 Strings'a', 'aa', 'aaa', 'Hello!', '11 cats' Return to the Top String Concatenation and Replication String concatenation:>>> 'Alice' 'Bob' 'AliceBob' Note: Avoid + operator for string concatenation. Prefer string formatting. String Replication:>>> 'Alice' * 5 'AliceAliceAliceAliceAlice' Return to the Top Variables You can name a variable anything as long as it obeys the following rules: It can be only one word. It can use only letters, numbers, and the underscore ( _) character. It can't begin with a number. Variable name starting with an underscore ( _) are considered as "unuseful`. Example:>>> spam = 'Hello' >>> spam 'Hello' >>> _spam = 'Hello' _spam should not be used again in the code. Return to the Top Comments Inline comment:# This is a comment Multiline comment:# This is a # multiline comment Code with a comment: a = 1 # initialization Please note the two spaces in front of the comment. Function docstring: def foo(): """ This is a function docstring You can also use: ''' Function Docstring ''' """ Return to the Top The print() Function>>> print('Hello world!') Hello world! >>> a = 1 >>> print('Hello world!', a) Hello world! 1 Return to the Top The input() Function Example Code:>>> print('What is your name?') # ask for their name >>> myName = input() >>> print('It is good to meet you, {}'.format(myName)) What is your name? Al It is good to meet you, Al Return to the Top The len() Function Evaluates to the integer value of the number of characters in a string:>>> len('hello') 5 Note: test of emptiness of strings, lists, dictionary, etc, should not use len, but prefer direct boolean evaluation.>>> a = [1, 2, 3] >>> if a: >>> print("the list is not empty!") Return to the Top The str(), int(), and float() Functions Integer to String or Float:>>> str(29) '29' >>> print('I am {} years old.'.format(str(29))) I am 29 years old. >>> str(-3.14) '-3.14' Float to Integer:>>> int(7.7) 7 >>> int(7.7) + 1 8 Return to the Top Flow Control Comparison Operators Operator Meaning== Equal to!= Not equal to< Less than> Greater Than<= Less than or Equal to>= Greater than or Equal to These operators evaluate to True or False depending on the values you give them. Examples:>>> 42 == 42 True >>> 40 == 42 False >>> 'hello' == 'hello' True >>> 'hello' == 'Hello' False >>> 'dog' != 'cat' True >>> 42 == 42.0 True >>> 42 == '42' False Boolean evaluation Never use == or != operator to evaluate boolean operation. Use the is or is not operators, or use implicit boolean evaluation. NO (even if they are valid Python):>>> True == True True >>> True != False True YES (even if they are valid Python):>>> True is True True >>> True is not False True These statements are equivalent:>>> if a is True: >>> pass >>> if a is not False: >>> pass >>> if a: >>> pass And these as well:>>> if a is False: >>> pass >>> if a is not True: >>> pass >>> if not a: >>> pass Return to the Top Boolean Operators There are three Boolean operators: and, or, and not. The and Operator's Truth Table: Expression Evaluates to True and True True True and False False False and True False False and False False The or Operator's Truth Table: Expression Evaluates to True or True True True or False True False or True True False or False False The not Operator's Truth Table: Expression Evaluates to not True False not False True Return to the Top Mixing Boolean and Comparison Operators>>> (4 < 5) and (5 < 6) True >>> (4 < 5) and (9 < 6) False >>> (1 == 2) or (2 == 2) True You can also use multiple Boolean operators in an expression, along with the comparison operators:>>> 2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2 True Return to the Top if Statements if name == 'Alice': print('Hi, Alice.') Return to the Top else Statements name = 'Bob' if name == 'Alice': print('Hi, Alice.') else: print('Hello, stranger.') Return to the Top elif Statements name = 'Bob' age = 5 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') name = 'Bob' age = 30 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') else: print('You are neither Alice nor a little kid.') Return to the Top while Loop Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 Return to the Top break Statements If the execution reaches a break statement, it immediately exits the while loop's clause: while True: print('Please type your name.') name = input() if name == 'your name': break print('Thank you!') Return to the Top continue Statements When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop. while True: print('Who are you?') name = input() if name != 'Joe': continue print('Hello, Joe. What is the password? (It is a fish.)') password = input() if password == 'swordfish': break print('Access granted.') Return to the Top for Loops and the range() Function>>> print('My name is') >>> for i in range(5): >>> print('Jimmy Five Times ({})'.format(str(i))) My name is Jimmy Five Times (0) Jimmy Five Times (1) Jimmy Five Times (2) Jimmy Five Times (3) Jimmy Five Times (4) The range() function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration.>>> for i in range(0, 10, 2): >>> print(i) 0 2 4 6 8 You can even use a negative number for the step argument to make the for loop count down instead of up.>>> for i in range(5, -1, -1): >>> print(i) 5 4 3 2 1 0 For else statement This allows to specify a statement to execute in case of the full loop has been executed. Only useful when a break condition can occur in the loop:>>> for i in [1, 2, 3, 4, 5]: >>> if i == 3: >>> break >>> else: >>> print("only executed when no item of the list is equal to 3") Return to the Top Importing Modules import random for i in range(5): print(random.randint(1, 10)) import random, sys, os, math from random import * Return to the Top Ending a Program Early with sys.exit() import sys while True: print('Type exit to exit.') response = input() if response == 'exit': sys.exit() print('You typed {}.'.format(response)) Return to the Top Functions>>> def hello(name): >>> print('Hello {}'.format(name)) >>> >>> hello('Alice') >>> hello('Bob') Hello Alice Hello Bob Return to the Top Return Values and return Statements When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following: The return keyword. The value or expression that the function should return. import random def getAnswer(answerNumber): if answerNumber == 1: return 'It is certain' elif answerNumber == 2: return 'It is decidedly so' elif answerNumber == 3: return 'Yes' elif answerNumber == 4: return 'Reply hazy try again' elif answerNumber == 5: return 'Ask again later' elif answerNumber == 6: return 'Concentrate and ask again' elif answerNumber == 7: return 'My reply is no' elif answerNumber == 8: return 'Outlook not so good' elif answerNumber == 9: return 'Very doubtful' r = random.randint(1, 9) fortune = getAnswer(r) print(fortune) Return to the Top The None Value>>> spam = print('Hello!') Hello! >>> spam is None True Note: never compare to None with the == operator. Always use is. Return to the Top Keyword Arguments and print()>>> print('Hello', end='') >>> print('World') HelloWorld >>> print('cats', 'dogs', 'mice') cats dogs mice >>> print('cats', 'dogs', 'mice', sep=',') cats,dogs,mice Return to the Top Local and Global Scope Code in the global scope cannot use any local variables. However, a local scope can access global variables. Code in a function's local scope cannot use variables in any other local scope. You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam. Return to the Top The global Statement If you need to modify a global variable from within a function, use the global statement:>>> def spam(): >>> global eggs >>> eggs = 'spam' >>> >>> eggs = 'global' >>> spam() >>> print(eggs) spam There are four rules to tell whether a variable is in a local scope or global scope: If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable. If there is a global statement for that variable in a function, it is a global variable. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable. But if the variable is not used in an assignment statement, it is a global variable. Return to the Top Exception Handling Basic exception handling>>> def spam(divideBy): >>> try: >>> return 42 / divideBy >>> except ZeroDivisionError as e: >>> print('Error: Invalid argument: {}'.format(e)) >>> >>> print(spam(2)) >>> print(spam(12)) >>> print(spam(0)) >>> print(spam(1)) 21.0 3.5 Error: Invalid argument: division by zero None 42.0 Return to the Top Final code in exception handling Code inside the finally section is always executed, no matter if an exception has been raised or not, and even if an exception is not caught.>>> def spam(divideBy): >>> try: >>> return 42 / divideBy >>> except ZeroDivisionError as e: >>> print('Error: Invalid argument: {}'.format(e)) >>> finally: >>> print("-- division finished --") >>> print(spam(2)) -- division finished -- 21.0 >>> print(spam(12)) -- division finished -- 3.5 >>> print(spam(0)) Error: Invalid Argument division by zero -- division finished -- None >>> print(spam(1)) -- division finished -- 42.0 Return to the Top Lists>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam ['cat', 'bat', 'rat', 'elephant'] Return to the Top Getting Individual Values in a List with Indexes>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[0] 'cat' >>> spam[1] 'bat' >>> spam[2] 'rat' >>> spam[3] 'elephant' Return to the Top Negative Indexes>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[-1] 'elephant' >>> spam[-3] 'bat' >>> 'The {} is afraid of the {}.'.format(spam[-1], spam[-3]) 'The elephant is afraid of the bat.' Return to the Top Getting Sublists with Slices>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[0:4] ['cat', 'bat', 'rat', 'elephant'] >>> spam[1:3] ['bat', 'rat'] >>> spam[0:-1] ['cat', 'bat', 'rat'] >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[:2] ['cat', 'bat'] >>> spam[1:] ['bat', 'rat', 'elephant'] Slicing the complete list will perform a copy:>>> spam2 = spam[:] ['cat', 'bat', 'rat', 'elephant'] >>> spam.append('dog') >>> spam ['cat', 'bat', 'rat', 'elephant', 'dog'] >>> spam2 ['cat', 'bat', 'rat', 'elephant'] Return to the Top Getting a List's Length with len()>>> spam = ['cat', 'dog', 'moose'] >>> len(spam) 3 Return to the Top Changing Values in a List with Indexes>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[1] = 'aardvark' >>> spam ['cat', 'aardvark', 'rat', 'elephant'] >>> spam[2] = spam[1] >>> spam ['cat', 'aardvark', 'aardvark', 'elephant'] >>> spam[-1] = 12345 >>> spam ['cat', 'aardvark', 'aardvark', 12345] Return to the Top List Concatenation and List Replication>>> [1, 2, 3] + ['A', 'B', 'C'] [1, 2, 3, 'A', 'B', 'C'] >>> ['X', 'Y', 'Z'] * 3 ['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z'] >>> spam = [1, 2, 3] >>> spam = spam + ['A', 'B', 'C'] >>> spam [1, 2, 3, 'A', 'B', 'C'] Return to the Top Removing Values from Lists with del Statements>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> del spam[2] >>> spam ['cat', 'bat', 'elephant'] >>> del spam[2] >>> spam ['cat', 'bat'] Return to the Top Using for Loops with Lists>>> supplies = ['pens', 'staplers', 'flame-throwers', 'binders'] >>> for i, supply in enumerate(supplies): >>> print('Index {} in supplies is: {}'.format(str(i), supply)) Index 0 in supplies is: pens Index 1 in supplies is: staplers Index 2 in supplies is: flame-throwers Index 3 in supplies is: binders Return to the Top Looping Through Multiple Lists with zip()>>> name = ['Pete', 'John', 'Elizabeth'] >>> age = [6, 23, 44] >>> for n, a in zip(name, age): >>> print('{} is {} years old'.format(n, a)) Pete is 6 years old John is 23 years old Elizabeth is 44 years old The in and not in Operators>>> 'howdy' in ['hello', 'hi', 'howdy', 'heyas'] True >>> spam = ['hello', 'hi', 'howdy', 'heyas'] >>> 'cat' in spam False >>> 'howdy' not in spam False >>> 'cat' not in spam True Return to the Top The Multiple Assignment Trick The multiple assignment trick is a shortcut that lets you assign multiple variables with the values in a list in one line of code. So instead of doing this:>>> cat = ['fat', 'orange', 'loud'] >>> size = cat[0] >>> color = cat[1] >>> disposition = cat[2] You could type this line of code:>>> cat = ['fat', 'orange', 'loud'] >>> size, color, disposition = cat The multiple assignment trick can also be used to swap the values in two variables:>>> a, b = 'Alice', 'Bob' >>> a, b = b, a >>> print(a) 'Bob' >>> print(b) 'Alice' Return to the Top Augmented Assignment Operators Operator Equivalent spam += 1 spam = spam + 1 spam -= 1 spam = spam - 1 spam *= 1 spam = spam * 1 spam /= 1 spam = spam / 1 spam %= 1 spam = spam % 1 Examples:>>> spam = 'Hello' >>> spam += ' world!' >>> spam 'Hello world!' >>> bacon = ['Zophie'] >>> bacon *= 3 >>> bacon ['Zophie', 'Zophie', 'Zophie'] Return to the Top Finding a Value in a List with the index() Method>>> spam = ['Zophie', 'Pooka', 'Fat-tail', 'Pooka'] >>> spam.index('Pooka') 1 Return to the Top Adding Values to Lists with the append() and insert() Methods append():>>> spam = ['cat', 'dog', 'bat'] >>> spam.append('moose') >>> spam ['cat', 'dog', 'bat', 'moose'] insert():>>> spam = ['cat', 'dog', 'bat'] >>> spam.insert(1, 'chicken') >>> spam ['cat', 'chicken', 'dog', 'bat'] Return to the Top Removing Values from Lists with remove()>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam.remove('bat') >>> spam ['cat', 'rat', 'elephant'] If the value appears multiple times in the list, only the first instance of the value will be removed. Return to the Top Removing Values from Lists with pop()>>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam.pop() 'elephant' >>> spam ['cat', 'bat', 'rat'] >>> spam.pop(0) 'cat' >>> spam ['bat', 'rat'] Return to the Top Sorting the Values in a List with the sort() Method>>> spam = [2, 5, 3.14, 1, -7] >>> spam.sort() >>> spam [-7, 1, 2, 3.14, 5] >>> spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants'] >>> spam.sort() >>> spam ['ants', 'badgers', 'cats', 'dogs', 'elephants'] You can also pass True for the reverse keyword argument to have sort() sort the values in reverse order:>>> spam.sort(reverse=True) >>> spam ['elephants', 'dogs', 'cats', 'badgers', 'ants'] If you need to sort the values in regular alphabetical order, pass str. lower for the key keyword argument in the sort() method call:>>> spam = ['a', 'z', 'A', 'Z'] >>> spam.sort(key=str.lower) >>> spam ['a', 'A', 'z', 'Z'] You can use the built-in function sorted to return a new list:>>> spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants'] >>> sorted(spam) ['ants', 'badgers', 'cats', 'dogs', 'elephants'] Return to the Top Tuple Data Type>>> eggs = ('hello', 42, 0.5) >>> eggs[0] 'hello' >>> eggs[1:3] (42, 0.5) >>> len(eggs) 3 The main way that tuples are different from lists is that tuples, like strings, are immutable. Return to the Top Converting Types with the list() and tuple() Functions>>> tuple(['cat', 'dog', 5]) ('cat', 'dog', 5) >>> list(('cat', 'dog', 5)) ['cat', 'dog', 5] >>> list('hello') ['h', 'e', 'l', 'l', 'o'] Return to the Top Dictionaries and Structuring Data Example Dictionary: myCat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'} Return to the Top The keys(), values(), and items() Methods values():>>> spam = {'color': 'red', 'age': 42} >>> for v in spam.values(): >>> print(v) red 42 keys():>>> for k in spam.keys(): >>> print(k) color age items():>>> for i in spam.items(): >>> print(i) ('color', 'red') ('age', 42) Using the keys(), values(), and items() methods, a for loop can iterate over the keys, values, or key-value pairs in a dictionary, respectively.>>> spam = {'color': 'red', 'age': 42} >>> >>> for k, v in spam.items(): >>> print('Key: {} Value: {}'.format(k, str(v))) Key: age Value: 42 Key: color Value: red Return to the Top Checking Whether a Key or Value Exists in a Dictionary>>> spam = {'name': 'Zophie', 'age': 7} >>> 'name' in spam.keys() True >>> 'Zophie' in spam.values() True >>> # You can omit the call to keys() when checking for a key >>> 'color' in spam False >>> 'color' not in spam True Return to the Top The get() Method Get has two parameters: key and default value if the key did not exist>>> picnic_items = {'apples': 5, 'cups': 2} >>> 'I am bringing {} cups.'.format(str(picnic_items.get('cups', 0))) 'I am bringing 2 cups.' >>> 'I am bringing {} eggs.'.format(str(picnic_items.get('eggs', 0))) 'I am bringing 0 eggs.' Return to the Top The setdefault() Method Let's consider this code: spam = {'name': 'Pooka', 'age': 5} if 'color' not in spam: spam['color'] = 'black' Using setdefault we could write the same code more succinctly:>>> spam = {'name': 'Pooka', 'age': 5} >>> spam.setdefault('color', 'black') 'black' >>> spam {'color': 'black', 'age': 5, 'name': 'Pooka'} >>> spam.setdefault('color', 'white') 'black' >>> spam {'color': 'black', 'age': 5, 'name': 'Pooka'} Return to the Top Pretty Printing>>> import pprint >>> >>> message = 'It was a bright cold day in April, and the clocks were striking >>> thirteen.' >>> count = {} >>> >>> for character in message: >>> count.setdefault(character, 0) >>> count[character] = count[character] + 1 >>> >>> pprint.pprint(count) {' ': 13, ',': 1, '.': 1, 'A': 1, 'I': 1, 'a': 4, 'b': 1, 'c': 3, 'd': 3, 'e': 5, 'g': 2, 'h': 3, 'i': 6, 'k': 2, 'l': 3, 'n': 4, 'o': 2, 'p': 1, 'r': 5, 's': 3, 't': 6, 'w': 2, 'y': 1} Return to the Top Merge two dictionaries# in Python 3.5+: >>> x = {'a': 1, 'b': 2} >>> y = {'b': 3, 'c': 4} >>> z = {**x, **y} >>> z {'c': 4, 'a': 1, 'b': 3} # in Python 2.7 >>> z = dict(x, **y) >>> z {'c': 4, 'a': 1, 'b': 3} sets From the Python 3 documentation A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference. Initializing a set There are two ways to create sets: using curly braces {} and the built-in function set()>>> s = {1, 2, 3} >>> s = set([1, 2, 3]) When creating an empty set, be sure to not use the curly braces {} or you will get an empty dictionary instead.>>> s = {} >>> type(s) <class 'dict'> sets: unordered collections of unique elements A set automatically remove all the duplicate values.>>> s = {1, 2, 3, 2, 3, 4} >>> s {1, 2, 3, 4} And as an unordered data type, they can't be indexed.>>> s = {1, 2, 3} >>> s[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'set' object does not support indexing >>> set add() and update() Using the add() method we can add a single element to the set.>>> s = {1, 2, 3} >>> s.add(4) >>> s {1, 2, 3, 4} And with update(), multiple ones .>>> s = {1, 2, 3} >>> s.update([2, 3, 4, 5, 6]) >>> s {1, 2, 3, 4, 5, 6} # remember, sets automatically remove duplicates set remove() and discard() Both methods will remove an element from the set, but remove() will raise a key error if the value doesn't exist.>>> s = {1, 2, 3} >>> s.remove(3) >>> s {1, 2} >>> s.remove(3) Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 3 discard() won't raise any errors.>>> s = {1, 2, 3} >>> s.discard(3) >>> s {1, 2} >>> s.discard(3) >>> set union() union() or | will create a new set that contains all the elements from the sets provided.>>> s1 = {1, 2, 3} >>> s2 = {3, 4, 5} >>> s1.union(s2) # or 's1 | s2' {1, 2, 3, 4, 5} set intersection intersection or & will return a set containing only the elements that are common to all of them.>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s3 = {3, 4, 5} >>> s1.intersection(s2, s3) # or 's1 & s2 & s3' {3} set difference difference or - will return only the elements that are unique to the first set (invoked set).>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.difference(s2) # or 's1 - s2' {1} >>> s2.difference(s1) # or 's2 - s1' {4} set symetric_difference symetric_difference or ^ will return all the elements that are not common between them.>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.symmetric_difference(s2) # or 's1 ^ s2' {1, 4} Return to the Top itertools Module The itertools module is a collection of tools intended to be fast and use memory efficiently when handling iterators (like lists or dictionaries). From the official Python 3.x documentation: The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python. The itertools module comes in the standard library and must be imported. The operator module will also be used. This module is not necessary when using itertools, but needed for some of the examples below. Return to the Top accumulate() Makes an iterator that returns the results of a function. itertools.accumulate(iterable[, func]) Example:>>> data = [1, 2, 3, 4, 5] >>> result = itertools.accumulate(data, operator.mul) >>> for each in result: >>> print(each) 1 2 6 24 120 The operator.mul takes two numbers and multiplies them: operator.mul(1, 2) 2 operator.mul(2, 3) 6 operator.mul(6, 4) 24 operator.mul(24, 5) 120 Passing a function is optional:>>> data = [5, 2, 6, 4, 5, 9, 1] >>> result = itertools.accumulate(data) >>> for each in result: >>> print(each) 5 7 13 17 22 31 32 If no function is designated the items will be summed: 5 5 + 2 = 7 7 + 6 = 13 13 + 4 = 17 17 + 5 = 22 22 + 9 = 31 31 + 1 = 32 Return to the Top combinations() Takes an iterable and a integer. This will create all the unique combination that have r members. itertools.combinations(iterable, r) Example:>>> shapes = ['circle', 'triangle', 'square',] >>> result = itertools.combinations(shapes, 2) >>> for each in result: >>> print(each) ('circle', 'triangle') ('circle', 'square') ('triangle', 'square') Return to the Top combinations with replacement() Just like combinations(), but allows individual elements to be repeated more than once. itertools.combinations_with_replacement(iterable, r) Example:>>> shapes = ['circle', 'triangle', 'square'] >>> result = itertools.combinations_with_replacement(shapes, 2) >>> for each in result: >>> print(each) ('circle', 'circle') ('circle', 'triangle') ('circle', 'square') ('triangle', 'triangle') ('triangle', 'square') ('square', 'square') Return to the Top count() Makes an iterator that returns evenly spaced values starting with number start. itertools.count(start=0, step=1) Example:>>> for i in itertools.count(10,3): >>> print(i) >>> if i > 20: >>> break 10 13 16 19 22 Return to the Top cycle() This function cycles through an iterator endlessly. itertools.cycle(iterable) Example:>>> colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet'] >>> for color in itertools.cycle(colors): >>> print(color) red orange yellow green blue violet red orange When reached the end of the iterable it start over again from the beginning. Return to the Top chain() Take a series of iterables and return them as one long iterable. itertools.chain(*iterables) Example:>>> colors = ['red', 'orange', 'yellow', 'green', 'blue'] >>> shapes = ['circle', 'triangle', 'square', 'pentagon'] >>> result = itertools.chain(colors, shapes) >>> for each in result: >>> print(each) red orange yellow green blue circle triangle square pentagon Return to the Top compress() Filters one iterable with another. itertools.compress(data, selectors) Example:>>> shapes = ['circle', 'triangle', 'square', 'pentagon'] >>> selections = [True, False, True, False] >>> result = itertools.compress(shapes, selections) >>> for each in result: >>> print(each) circle square Return to the Top dropwhile() Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. itertools.dropwhile(predicate, iterable) Example:>>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1] >>> result = itertools.dropwhile(lambda x: x<5, data) >>> for each in result: >>> print(each) 5 6 7 8 9 10 1 Return to the Top filterfalse() Makes an iterator that filters elements from iterable returning only those for which the predicate is False. itertools.filterfalse(predicate, iterable) Example:>>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1] >>> result = itertools.filterfalse(lambda x: x<5, data) >>> for each in result: >>> print(each) 5 6 7 8 9 10 Return to the Top groupby() Simply put, this function groups things together. itertools.groupby(iterable, key=None) Example:>>> robots = [{ 'name': 'blaster', 'faction': 'autobot' }, { 'name': 'galvatron', 'faction': 'decepticon' }, { 'name': 'jazz', 'faction': 'autobot' }, { 'name': 'metroplex', 'faction': 'autobot' }, { 'name': 'megatron', 'faction': 'decepticon' }, { 'name': 'starcream', 'faction': 'decepticon' }] >>> for key, group in itertools.groupby(robots, key=lambda x: x['faction']): >>> print(key) >>> print(list(group)) autobot [{'name': 'blaster', 'faction': 'autobot'}] decepticon [{'name': 'galvatron', 'faction': 'decepticon'}] autobot [{'name': 'jazz', 'faction': 'autobot'}, {'name': 'metroplex', 'faction': 'autobot'}] decepticon [{'name': 'megatron', 'faction': 'decepticon'}, {'name': 'starcream', 'faction': 'decepticon'}] Return to the Top islice() This function is very much like slices. This allows you to cut out a piece of an iterable. itertools.islice(iterable, start, stop[, step]) Example:>>> colors = ['red', 'orange', 'yellow', 'green', 'blue',] >>> few_colors = itertools.islice(colors, 2) >>> for each in few_colors: >>> print(each) red orange Return to the Top permutations() itertools.permutations(iterable, r=None) Example:>>> alpha_data = ['a', 'b', 'c'] >>> result = itertools.permutations(alpha_data) >>> for each in result: >>> print(each) ('a', 'b', 'c') ('a', 'c', 'b') ('b', 'a', 'c') ('b', 'c', 'a') ('c', 'a', 'b') ('c', 'b', 'a') Return to the Top product() Creates the cartesian products from a series of iterables.>>> num_data = [1, 2, 3] >>> alpha_data = ['a', 'b', 'c'] >>> result = itertools.product(num_data, alpha_data) >>> for each in result: print(each) (1, 'a') (1, 'b') (1, 'c') (2, 'a') (2, 'b') (2, 'c') (3, 'a') (3, 'b') (3, 'c') Return to the Top repeat() This function will repeat an object over and over again. Unless, there is a times argument. itertools.repeat(object[, times]) Example:>>> for i in itertools.repeat("spam", 3): print(i) spam spam spam Return to the Top starmap() Makes an iterator that computes the function using arguments obtained from the iterable. itertools.starmap(function, iterable) Example:>>> data = [(2, 6), (8, 4), (7, 3)] >>> result = itertools.starmap(operator.mul, data) >>> for each in result: >>> print(each) 12 32 21 Return to the Top takewhile() The opposite of dropwhile(). Makes an iterator and returns elements from the iterable as long as the predicate is true. itertools.takewhile(predicate, iterable) Example:>>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1] >>> result = itertools.takewhile(lambda x: x<5, data) >>> for each in result: >>> print(each) 1 2 3 4 Return to the Top tee() Return n independent iterators from a single iterable. itertools.tee(iterable, n=2) Example:>>> colors = ['red', 'orange', 'yellow', 'green', 'blue'] >>> alpha_colors, beta_colors = itertools.tee(colors) >>> for each in alpha_colors: >>> print(each) red orange yellow green blue >>> colors = ['red', 'orange', 'yellow', 'green', 'blue'] >>> alpha_colors, beta_colors = itertools.tee(colors) >>> for each in beta_colors: >>> print(each) red orange yellow green blue Return to the Top zip_longest() Makes an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted. itertools.zip_longest(*iterables, fillvalue=None) Example:>>> colors = ['red', 'orange', 'yellow', 'green', 'blue',] >>> data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,] >>> for each in itertools.zip_longest(colors, data, fillvalue=None): >>> print(each) ('red', 1) ('orange', 2) ('yellow', 3) ('green', 4) ('blue', 5) (None, 6) (None, 7) (None, 8) (None, 9) (None, 10) Return to the Top Comprehensions List comprehension>>> a = [1, 3, 5, 7, 9, 11] >>> [i - 1 for i in a] [0, 2, 4, 6, 8, 10] Set comprehension>>> b = {"abc", "def"} >>> {s.upper() for s in b} {"ABC", "DEF"} Dict comprehension>>> c = {'name': 'Pooka', 'age': 5} >>> {v: k for k, v in c.items()} {'Pooka': 'name', 5: 'age'} A List comprehension can be generated from a dictionary:>>> c = {'name': 'Pooka', 'first_name': 'Oooka'} >>> ["{}:{}".format(k.upper(), v.upper()) for k, v in c.items()] ['NAME:POOKA', 'FIRST_NAME:OOOKA'] Manipulating Strings Escape Characters Escape character Prints as\' Single quote\" Double quote\t Tab\n Newline (line break)\\ Backslash\b Backspace\ooo Octal value\r Carriage Return Example:>>> print("Hello there!\nHow are you?\nI\'m doing fine.") Hello there! How are you? I'm doing fine. Return to the Top Raw Strings A raw string completely ignores all escape characters and prints any backslash that appears in the string.>>> print(r'That is Carol\'s cat.') That is Carol\'s cat. Note: mostly used for regular expression definition (see re package) Return to the Top Multiline Strings with Triple Quotes>>> print('''Dear Alice, >>> >>> Eve's cat has been arrested for catnapping, cat burglary, and extortion. >>> >>> Sincerely, >>> Bob''') Dear Alice, Eve's cat has been arrested for catnapping, cat burglary, and extortion. Sincerely, Bob To keep a nicer flow in your code, you can use the dedent function from the textwrap standard package.>>> from textwrap import dedent >>> >>> def my_function(): >>> print(''' >>> Dear Alice, >>> >>> Eve's cat has been arrested for catnapping, cat burglary, and extortion. >>> >>> Sincerely, >>> Bob >>> ''').strip() This generates the same string than before. Return to the Top Indexing and Slicing Strings H e l l o w o r l d ! 0 1 2 3 4 5 6 7 8 9 10 11 >>> spam = 'Hello world!' >>> spam[0] 'H' >>> spam[4] 'o' >>> spam[-1] '!' Slicing:>>> spam[0:5] 'Hello' >>> spam[:5] 'Hello' >>> spam[6:] 'world!' >>> spam[6:-1] 'world' >>> spam[:-1] 'Hello world' >>> spam[::-1] '!dlrow olleH' >>> spam = 'Hello world!' >>> fizz = spam[0:5] >>> fizz 'Hello' Return to the Top The in and not in Operators with Strings>>> 'Hello' in 'Hello World' True >>> 'Hello' in 'Hello' True >>> 'HELLO' in 'Hello World' False >>> '' in 'spam' True >>> 'cats' not in 'cats and dogs' False The in and not in Operators with list>>> a = [1, 2, 3, 4] >>> 5 in a False >>> 2 in a True Return to the Top The upper(), lower(), isupper(), and islower() String Methods upper() and lower():>>> spam = 'Hello world!' >>> spam = spam.upper() >>> spam 'HELLO WORLD!' >>> spam = spam.lower() >>> spam 'hello world!' isupper() and islower():>>> spam = 'Hello world!' >>> spam.islower() False >>> spam.isupper() False >>> 'HELLO'.isupper() True >>> 'abc12345'.islower() True >>> '12345'.islower() False >>> '12345'.isupper() False Return to the Top The isX String Methods isalpha() returns True if the string consists only of letters and is not blank. isalnum() returns True if the string consists only of letters and numbers and is not blank. isdecimal() returns True if the string consists only of numeric characters and is not blank. isspace() returns True if the string consists only of spaces,tabs, and new-lines and is not blank. istitle() returns True if the string consists only of words that begin with an uppercase letter followed by only lowercase letters. Return to the Top The startswith() and endswith() String Methods>>> 'Hello world!'.startswith('Hello') True >>> 'Hello world!'.endswith('world!') True >>> 'abc123'.startswith('abcdef') False >>> 'abc123'.endswith('12') False >>> 'Hello world!'.startswith('Hello world!') True >>> 'Hello world!'.endswith('Hello world!') True Return to the Top The join() and split() String Methods join():>>> ', '.join(['cats', 'rats', 'bats']) 'cats, rats, bats' >>> ' '.join(['My', 'name', 'is', 'Simon']) 'My name is Simon' >>> 'ABC'.join(['My', 'name', 'is', 'Simon']) 'MyABCnameABCisABCSimon' split():>>> 'My name is Simon'.split() ['My', 'name', 'is', 'Simon'] >>> 'MyABCnameABCisABCSimon'.split('ABC') ['My', 'name', 'is', 'Simon'] >>> 'My name is Simon'.split('m') ['My na', 'e is Si', 'on'] Return to the Top Justifying Text with rjust(), ljust(), and center() rjust() and ljust():>>> 'Hello'.rjust(10) ' Hello' >>> 'Hello'.rjust(20) ' Hello' >>> 'Hello World'.rjust(20) ' Hello World' >>> 'Hello'.ljust(10) 'Hello ' An optional second argument to rjust() and ljust() will specify a fill character other than a space character. Enter the following into the interactive shell:>>> 'Hello'.rjust(20, '*') '***************Hello' >>> 'Hello'.ljust(20, '-') 'Hello---------------' center():>>> 'Hello'.center(20) ' Hello ' >>> 'Hello'.center(20, '=') '=======Hello========' Return to the Top Removing Whitespace with strip(), rstrip(), and lstrip()>>> spam = ' Hello World ' >>> spam.strip() 'Hello World' >>> spam.lstrip() 'Hello World ' >>> spam.rstrip() ' Hello World' >>> spam = 'SpamSpamBaconSpamEggsSpamSpam' >>> spam.strip('ampS') 'BaconSpamEggs' Return to the Top Copying and Pasting Strings with the pyperclip Module (need pip install)>>> import pyperclip >>> pyperclip.copy('Hello world!') >>> pyperclip.paste() 'Hello world!' Return to the Top String Formatting% operator>>> name = 'Pete' >>> 'Hello %s' % name "Hello Pete" We can use the %x format specifier to convert an int value to a string:>>> num = 5 >>> 'I have %x apples' % num "I have 5 apples" Note: For new code, using str.format or f-strings (Python 3.6+) is strongly recommended over the % operator. Return to the Top String Formatting (str.format) Python 3 introduced a new way to do string formatting that was later back-ported to Python 2.7. This makes the syntax for string formatting more regular.>>> name = 'John' >>> age = 20' >>> "Hello I'm {}, my age is {}".format(name, age) "Hello I'm John, my age is 20" >>> "Hello I'm {0}, my age is {1}".format(name, age) "Hello I'm John, my age is 20" The official Python 3.x documentation recommend str.format over the % operator: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text. Return to the Top Lazy string formatting You would only use %s string formatting on functions that can do lazy parameters evaluation, the most common being logging: Prefer:>>> name = "alice" >>> logging.debug("User name: %s", name) Over:>>> logging.debug("User name: {}".format(name)) Or:>>> logging.debug("User name: " + name) Return to the Top Formatted String Literals or f-strings (Python 3.6+)>>> name = 'Elizabeth' >>> f'Hello {name}!' 'Hello Elizabeth! It is even possible to do inline arithmetic with it:>>> a = 5 >>> b = 10 >>> f'Five plus ten is {a + b} and not {2 * (a + b)}.' 'Five plus ten is 15 and not 30.' Return to the Top Template Strings A simpler and less powerful mechanism, but it is recommended when handling format strings generated by users. Due to their reduced complexity template strings are a safer choice.>>> from string import Template >>> name = 'Elizabeth' >>> t = Template('Hey $name!') >>> t.substitute(name=name) 'Hey Elizabeth!' Return to the Top Regular Expressions Import the regex module with import re. Create a Regex object with the re.compile() function. (Remember to use a raw string.) Pass the string you want to search into the Regex object's search() method. This returns a Match object. Call the Match object's group() method to return a string of the actual matched text. All the regex functions in Python are in the re module:>>> import re Return to the Top Matching Regex Objects>>> phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') >>> mo = phone_num_regex.search('My number is 415-555-4242.') >>> print('Phone number found: {}'.format(mo.group())) Phone number found: 415-555-4242 Return to the Top Grouping with Parentheses>>> phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') >>> mo = phone_num_regex.search('My number is 415-555-4242.') >>> mo.group(1) '415' >>> mo.group(2) '555-4242' >>> mo.group(0) '415-555-4242' >>> mo.group() '415-555-4242' To retrieve all the groups at once: use the groups() method—note the plural form for the name.>>> mo.groups() ('415', '555-4242') >>> area_code, main_number = mo.groups() >>> print(area_code) 415 >>> print(main_number) 555-4242 Return to the Top Matching Multiple Groups with the Pipe The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r'Batman|Tina Fey' will match either 'Batman' or 'Tina Fey'.>>> hero_regex = re.compile (r'Batman|Tina Fey') >>> mo1 = hero_regex.search('Batman and Tina Fey.') >>> mo1.group() 'Batman' >>> mo2 = hero_regex.search('Tina Fey and Batman.') >>> mo2.group() 'Tina Fey' You can also use the pipe to match one of several patterns as part of your regex:>>> bat_regex = re.compile(r'Bat(man|mobile|copter|bat)') >>> mo = bat_regex.search('Batmobile lost a wheel') >>> mo.group() 'Batmobile' >>> mo.group(1) 'mobile' Return to the Top Optional Matching with the Question Mark The ? character flags the group that precedes it as an optional part of the pattern.>>> bat_regex = re.compile(r'Bat(wo)?man') >>> mo1 = bat_regex.search('The Adventures of Batman') >>> mo1.group() 'Batman' >>> mo2 = bat_regex.search('The Adventures of Batwoman') >>> mo2.group() 'Batwoman' Return to the Top Matching Zero or More with the Star The * (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text.>>> bat_regex = re.compile(r'Bat(wo)*man') >>> mo1 = bat_regex.search('The Adventures of Batman') >>> mo1.group() 'Batman' >>> mo2 = bat_regex.search('The Adventures of Batwoman') >>> mo2.group() 'Batwoman' >>> mo3 = bat_regex.search('The Adventures of Batwowowowoman') >>> mo3.group() 'Batwowowowoman' Return to the Top Matching One or More with the Plus While * means “match zero or more,” the + (or plus) means “match one or more”. The group preceding a plus must appear at least once. It is not optional:>>> bat_regex = re.compile(r'Bat(wo)+man') >>> mo1 = bat_regex.search('The Adventures of Batwoman') >>> mo1.group() 'Batwoman' >>> mo2 = bat_regex.search('The Adventures of Batwowowowoman') >>> mo2.group() 'Batwowowowoman' >>> mo3 = bat_regex.search('The Adventures of Batman') >>> mo3 is None True Return to the Top Matching Specific Repetitions with Curly Brackets If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string 'HaHaHa', but it will not match 'HaHa', since the latter has only two repeats of the (Ha) group. Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3,5} will match 'HaHaHa', 'HaHaHaHa', and 'HaHaHaHaHa'.>>> ha_regex = re.compile(r'(Ha){3}') >>> mo1 = ha_regex.search('HaHaHa') >>> mo1.group() 'HaHaHa' >>> mo2 = ha_regex.search('Ha') >>> mo2 is None True Return to the Top Greedy and Nongreedy Matching Python's regular expressions are greedy by default, which means that in ambiguous situations they will match the longest string possible. The non-greedy version of the curly brackets, which matches the shortest string possible, has the closing curly bracket followed by a question mark.>>> greedy_ha_regex = re.compile(r'(Ha){3,5}') >>> mo1 = greedy_ha_regex.search('HaHaHaHaHa') >>> mo1.group() 'HaHaHaHaHa' >>> nongreedy_ha_regex = re.compile(r'(Ha){3,5}?') >>> mo2 = nongreedy_ha_regex.search('HaHaHaHaHa') >>> mo2.group() 'HaHaHa' Return to the Top The findall() Method In addition to the search() method, Regex objects also have a findall() method. While search() will return a Match object of the first matched text in the searched string, the findall() method will return the strings of every match in the searched string.>>> phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups >>> phone_num_regex.findall('Cell: 415-555-9999 Work: 212-555-0000') ['415-555-9999', '212-555-0000'] To summarize what the findall() method returns, remember the following: When called on a regex with no groups, such as \d-\d\d\d-\d\d\d\d, the method findall() returns a list of ng matches, such as ['415-555-9999', '212-555-0000']. When called on a regex that has groups, such as (\d\d\d)-(d\d)-(\d\d\d\d), the method findall() returns a list of es of strings (one string for each group), such as [('415', '555', '9999'), ('212', '555', '0000')]. Return to the Top Making Your Own Character Classes There are times when you want to match a set of characters but the shorthand character classes (\d, \w, \s, and so on) are too broad. You can define your own character class using square brackets. For example, the character class [aeiouAEIOU] will match any vowel, both lowercase and uppercase.>>> vowel_regex = re.compile(r'[aeiouAEIOU]') >>> vowel_regex.findall('Robocop eats baby food. BABY FOOD.') ['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O'] You can also include ranges of letters or numbers by using a hyphen. For example, the character class [a-zA-Z0-9] will match all lowercase letters, uppercase letters, and numbers. By placing a caret character (^) just after the character class's opening bracket, you can make a negative character class. A negative character class will match all the characters that are not in the character class. For example, enter the following into the interactive shell:>>> consonant_regex = re.compile(r'[^aeiouAEIOU]') >>> consonant_regex.findall('Robocop eats baby food. BABY FOOD.') ['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.'] Return to the Top The Caret and Dollar Sign Characters You can also use the caret symbol (^) at the start of a regex to indicate that a match must occur at the beginning of the searched text. Likewise, you can put a dollar sign ($) at the end of the regex to indicate the string must end with this regex pattern. And you can use the ^ and $ together to indicate that the entire string must match the regex—that is, it's not enough for a match to be made on some subset of the string. The r'^Hello' regular expression string matches strings that begin with 'Hello':>>> begins_with_hello = re.compile(r'^Hello') >>> begins_with_hello.search('Hello world!') <_sre.SRE_Match object; span=(0, 5), match='Hello'> >>> begins_with_hello.search('He said hello.') is None True The r'\d$' regular expression string matches strings that end with a numeric character from 0 to 9:>>> whole_string_is_num = re.compile(r'^\d+$') >>> whole_string_is_num.search('1234567890') <_sre.SRE_Match object; span=(0, 10), match='1234567890'> >>> whole_string_is_num.search('12345xyz67890') is None True >>> whole_string_is_num.search('12 34567890') is None True Return to the Top The Wildcard Character The . (or dot) character in a regular expression is called a wildcard and will match any character except for a newline:>>> at_regex = re.compile(r'.at') >>> at_regex.findall('The cat in the hat sat on the flat mat.') ['cat', 'hat', 'sat', 'lat', 'mat'] Return to the Top Matching Everything with Dot-Star>>> name_regex = re.compile(r'First Name: (.*) Last Name: (.*)') >>> mo = name_regex.search('First Name: Al Last Name: Sweigart') >>> mo.group(1) 'Al' >>> mo.group(2) 'Sweigart' The dot-star uses greedy mode: It will always try to match as much text as possible. To match any and all text in a nongreedy fashion, use the dot, star, and question mark (.*?). The question mark tells Python to match in a nongreedy way:>>> nongreedy_regex = re.compile(r'<.*?>') >>> mo = nongreedy_regex.search('<To serve man> for dinner.>') >>> mo.group() '<To serve man>' >>> greedy_regex = re.compile(r'<.*>') >>> mo = greedy_regex.search('<To serve man> for dinner.>') >>> mo.group() '<To serve man> for dinner.>' Return to the Top Matching Newlines with the Dot Character The dot-star will match everything except a newline. By passing re.DOTALL as the second argument to re.compile(), you can make the dot character match all characters, including the newline character:>>> no_newline_regex = re.compile('.*') >>> no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() 'Serve the public trust.' >>> newline_regex = re.compile('.*', re.DOTALL) >>> newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() 'Serve the public trust.\nProtect the innocent.\nUphold the law.' Return to the Top Review of Regex Symbols Symbol Matches? zero or one of the preceding group.* zero or more of the preceding group.+ one or more of the preceding group.{n} exactly n of the preceding group.{n,} n or more of the preceding group.{,m} 0 to m of the preceding group.{n,m} at least n and at most m of the preceding p.{n,m}? or *? or +? performs a nongreedy match of the preceding p.^spam means the string must begin with spam. spam$ means the string must end with spam.. any character, except newline characters.\d, \w, and \s a digit, word, or space character, respectively.\D, \W, and \S anything except a digit, word, or space, respectively.[abc] any character between the brackets (such as a, b, ).[^abc] any character that isn't between the brackets. Return to the Top Case-Insensitive Matching To make your regex case-insensitive, you can pass re.IGNORECASE or re.I as a second argument to re.compile():>>> robocop = re.compile(r'robocop', re.I) >>> robocop.search('Robocop is part man, part machine, all cop.').group() 'Robocop' >>> robocop.search('ROBOCOP protects the innocent.').group() 'ROBOCOP' >>> robocop.search('Al, why does your programming book talk about robocop so much?').group() 'robocop' Return to the Top Substituting Strings with the sub() Method The sub() method for Regex objects is passed two arguments: The first argument is a string to replace any matches. The second is the string for the regular expression. The sub() method returns a string with the substitutions applied:>>> names_regex = re.compile(r'Agent \w+') >>> names_regex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.') 'CENSORED gave the secret documents to CENSORED.' Another example:>>> agent_names_regex = re.compile(r'Agent (\w)\w*') >>> agent_names_regex.sub(r'\1****', 'Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.') A**** told C**** that E**** knew B**** was a double agent.' Return to the Top Managing Complex Regexes To tell the re.compile() function to ignore whitespace and comments inside the regular expression string, “verbose mode” can be enabled by passing the variable re.VERBOSE as the second argument to re.compile(). Now instead of a hard-to-read regular expression like this: phone_regex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)') you can spread the regular expression over multiple lines with comments like this: phone_regex = re.compile(r'''( (\d{3}|\(\d{3}\))? # area code (\s|-|\.)? # separator \d{3} # first 3 digits (\s|-|\.) # separator \d{4} # last 4 digits (\s*(ext|x|ext.)\s*\d{2,5})? # extension )''', re.VERBOSE) Return to the Top Handling File and Directory Paths There are two main modules in Python that deals with path manipulation. One is the os.path module and the other is the pathlib module. The pathlib module was added in Python 3.4, offering an object-oriented way to handle file system paths. Return to the Top Backslash on Windows and Forward Slash on OS X and Linux On Windows, paths are written using backslashes (\) as the separator between folder names. On Unix based operating system such as macOS, Linux, and BSDs, the forward slash (/) is used as the path separator. Joining paths can be a headache if your code needs to work on different platforms. Fortunately, Python provides easy ways to handle this. We will showcase how to deal with this with both os.path.join and pathlib.Path.joinpath Using os.path.join on Windows:>>> import os >>> os.path.join('usr', 'bin', 'spam') 'usr\\bin\\spam' And using pathlib on *nix:>>> from pathlib import Path >>> print(Path('usr').joinpath('bin').joinpath('spam')) usr/bin/spam pathlib also provides a shortcut to joinpath using the / operator:>>> from pathlib import Path >>> print(Path('usr') / 'bin' / 'spam') usr/bin/spam Notice the path separator is different between Windows and Unix based operating system, that's why you want to use one of the above methods instead of adding strings together to join paths together. Joining paths is helpful if you need to create different file paths under the same directory. Using os.path.join on Windows:>>> my_files = ['accounts.txt', 'details.csv', 'invite.docx'] >>> for filename in my_files: >>> print(os.path.join('C:\\Users\\asweigart', filename)) C:\Users\asweigart\accounts.txt C:\Users\asweigart\details.csv C:\Users\asweigart\invite.docx Using pathlib on *nix:>>> my_files = ['accounts.txt', 'details.csv', 'invite.docx'] >>> home = Path.home() >>> for filename in my_files: >>> print(home / filename) /home/asweigart/accounts.txt /home/asweigart/details.csv /home/asweigart/invite.docx Return to the Top The Current Working Directory Using os on Windows:>>> import os >>> os.getcwd() 'C:\\Python34' >>> os.chdir('C:\\Windows\\System32') >>> os.getcwd() 'C:\\Windows\\System32' Using pathlib on *nix:>>> from pathlib import Path >>> from os import chdir >>> print(Path.cwd()) /home/asweigart >>> chdir('/usr/lib/python3.6') >>> print(Path.cwd()) /usr/lib/python3.6 Return to the Top Creating New Folders Using os on Windows:>>> import os >>> os.makedirs('C:\\delicious\\walnut\\waffles') Using pathlib on *nix:>>> from pathlib import Path >>> cwd = Path.cwd() >>> (cwd / 'delicious' / 'walnut' / 'waffles').mkdir() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.6/pathlib.py", line 1226, in mkdir self._accessor.mkdir(self, mode) File "/usr/lib/python3.6/pathlib.py", line 387, in wrapped return strfunc(str(pathobj), *args) FileNotFoundError: [Errno 2] No such file or directory: '/home/asweigart/delicious/walnut/waffles' Oh no, we got a nasty error! The reason is that the 'delicious' directory does not exist, so we cannot make the 'walnut' and the 'waffles' directories under it. To fix this, do:>>> from pathlib import Path >>> cwd = Path.cwd() >>> (cwd / 'delicious' / 'walnut' / 'waffles').mkdir(parents=True) And all is good :) Return to the Top Absolute vs. Relative Paths There are two ways to specify a file path. An absolute path, which always begins with the root folder A relative path, which is relative to the program's current working directory There are also the dot (.) and dot-dot (..) folders. These are not real folders but special names that can be used in a path. A single period (“dot”) for a folder name is shorthand for “this directory.” Two periods (“dot-dot”) means “the parent folder.” Return to the Top Handling Absolute and Relative Paths To see if a path is an absolute path: Using os.path on *nix:>>> import os >>> os.path.isabs('/') True >>> os.path.isabs('..') False Using pathlib on *nix:>>> from pathlib import Path >>> Path('/').is_absolute() True >>> Path('..').is_absolute() False You can extract an absolute path with both os.path and pathlib Using os.path on *nix:>>> import os >>> os.getcwd() '/home/asweigart' >>> os.path.abspath('..') '/home' Using pathlib on *nix: from pathlib import Path print(Path.cwd()) /home/asweigart print(Path('..').resolve()) /home You can get a relative path from a starting path to another path. Using os.path on *nix:>>> import os >>> os.path.relpath('/etc/passwd', '/') 'etc/passwd' Using pathlib on *nix:>>> from pathlib import Path >>> print(Path('/etc/passwd').relative_to('/')) etc/passwd Return to the Top Checking Path Validity Checking if a file/directory exists: Using os.path on *nix: import os >>> os.path.exists('.') True >>> os.path.exists('setup.py') True >>> os.path.exists('/etc') True >>> os.path.exists('nonexistentfile') False Using pathlib on *nix: from pathlib import Path >>> Path('.').exists() True >>> Path('setup.py').exists() True >>> Path('/etc').exists() True >>> Path('nonexistentfile').exists() False Checking if a path is a file: Using os.path on *nix:>>> import os >>> os.path.isfile('setup.py') True >>> os.path.isfile('/home') False >>> os.path.isfile('nonexistentfile') False Using pathlib on *nix:>>> from pathlib import Path >>> Path('setup.py').is_file() True >>> Path('/home').is_file() False >>> Path('nonexistentfile').is_file() False Checking if a path is a directory: Using os.path on *nix:>>> import os >>> os.path.isdir('/') True >>> os.path.isdir('setup.py') False >>> os.path.isdir('/spam') False Using pathlib on *nix:>>> from pathlib import Path >>> Path('/').is_dir() True >>> Path('setup.py').is_dir() False >>> Path('/spam').is_dir() False Return to the Top Finding File Sizes and Folder Contents Getting a file's size in bytes: Using os.path on Windows:>>> import os >>> os.path.getsize('C:\\Windows\\System32\\calc.exe') 776192 Using pathlib on *nix:>>> from pathlib import Path >>> stat = Path('/bin/python3.6').stat() >>> print(stat) # stat contains some other information about the file as well os.stat_result(st_mode=33261, st_ino=141087, st_dev=2051, st_nlink=2, st_uid=0, --snip-- st_gid=0, st_size=10024, st_atime=1517725562, st_mtime=1515119809, st_ctime=1517261276) >>> print(stat.st_size) # size in bytes 10024 Listing directory contents using os.listdir on Windows:>>> import os >>> os.listdir('C:\\Windows\\System32') ['0409', '12520437.cpx', '12520850.cpx', '5U877.ax', 'aaclient.dll', --snip-- 'xwtpdui.dll', 'xwtpw32.dll', 'zh-CN', 'zh-HK', 'zh-TW', 'zipfldr.dll'] Listing directory contents using pathlib on *nix:>>> from pathlib import Path >>> for f in Path('/usr/bin').iterdir(): >>> print(f) ... /usr/bin/tiff2rgba /usr/bin/iconv /usr/bin/ldd /usr/bin/cache_restore /usr/bin/udiskie /usr/bin/unix2dos /usr/bin/t1reencode /usr/bin/epstopdf /usr/bin/idle3 ... To find the total size of all the files in this directory: WARNING: Directories themselves also have a size! So you might want to check for whether a path is a file or directory using the methods in the methods discussed in the above section! Using os.path.getsize() and os.listdir() together on Windows:>>> import os >>> total_size = 0 >>> for filename in os.listdir('C:\\Windows\\System32'): total_size = total_size + os.path.getsize(os.path.join('C:\\Windows\\System32', filename)) >>> print(total_size) 1117846456 Using pathlib on *nix:>>> from pathlib import Path >>> total_size = 0 >>> for sub_path in Path('/usr/bin').iterdir(): ... total_size += sub_path.stat().st_size >>> >>> print(total_size) 1903178911 Return to the Top Copying Files and Folders The shutil module provides functions for copying files, as well as entire folders.>>> import shutil, os >>> os.chdir('C:\\') >>> shutil.copy('C:\\spam.txt', 'C:\\delicious') 'C:\\delicious\\spam.txt' >>> shutil.copy('eggs.txt', 'C:\\delicious\\eggs2.txt') 'C:\\delicious\\eggs2.txt' While shutil.copy() will copy a single file, shutil.copytree() will copy an entire folder and every folder and file contained in it:>>> import shutil, os >>> os.chdir('C:\\') >>> shutil.copytree('C:\\bacon', 'C:\\bacon_backup') 'C:\\bacon_backup' Return to the Top Moving and Renaming Files and Folders>>> import shutil >>> shutil.move('C:\\bacon.txt', 'C:\\eggs') 'C:\\eggs\\bacon.txt' The destination path can also specify a filename. In the following example, the source file is moved and renamed:>>> shutil.move('C:\\bacon.txt', 'C:\\eggs\\new_bacon.txt') 'C:\\eggs\\new_bacon.txt' If there is no eggs folder, then move() will rename bacon.txt to a file named eggs.>>> shutil.move('C:\\bacon.txt', 'C:\\eggs') 'C:\\eggs' Return to the Top Permanently Deleting Files and Folders Calling os.unlink(path) or Path.unlink() will delete the file at path. Calling os.rmdir(path) or Path.rmdir() will delete the folder at path. This folder must be empty of any files or folders. Calling shutil.rmtree(path) will remove the folder at path, and all files and folders it contains will also be deleted. Return to the Top Safe Deletes with the send2trash Module You can install this module by running pip install send2trash from a Terminal window.>>> import send2trash >>> with open('bacon.txt', 'a') as bacon_file: # creates the file ... bacon_file.write('Bacon is not a vegetable.') 25 >>> send2trash.send2trash('bacon.txt') Return to the Top Walking a Directory Tree>>> import os >>> >>> for folder_name, subfolders, filenames in os.walk('C:\\delicious'): >>> print('The current folder is {}'.format(folder_name)) >>> >>> for subfolder in subfolders: >>> print('SUBFOLDER OF {}: {}'.format(folder_name, subfolder)) >>> for filename in filenames: >>> print('FILE INSIDE {}: {}'.format(folder_name, filename)) >>> >>> print('') The current folder is C:\delicious SUBFOLDER OF C:\delicious: cats SUBFOLDER OF C:\delicious: walnut FILE INSIDE C:\delicious: spam.txt The current folder is C:\delicious\cats FILE INSIDE C:\delicious\cats: catnames.txt FILE INSIDE C:\delicious\cats: zophie.jpg The current folder is C:\delicious\walnut SUBFOLDER OF C:\delicious\walnut: waffles The current folder is C:\delicious\walnut\waffles FILE INSIDE C:\delicious\walnut\waffles: butter.txt Return to the Top pathlib provides a lot more functionality than the ones listed above, like getting file name, getting file extension, reading/writing a file without manually opening it, etc. Check out the official documentation if you want to know more! Reading and Writing Files The File Reading/Writing Process To read/write to a file in Python, you will want to use the with statement, which will close the file for you after you are done. Return to the Top Opening and reading files with the open() function>>> with open('C:\\Users\\your_home_folder\\hello.txt') as hello_file: ... hello_content = hello_file.read() >>> hello_content 'Hello World!' >>> # Alternatively, you can use the *readlines()* method to get a list of string values from the file, one string for each line of text: >>> with open('sonnet29.txt') as sonnet_file: ... sonnet_file.readlines() [When, in disgrace with fortune and men's eyes,\n', ' I all alone beweep my outcast state,\n', And trouble deaf heaven with my bootless cries,\n', And look upon myself and curse my fate,'] >>> # You can also iterate through the file line by line: >>> with open('sonnet29.txt') as sonnet_file: ... for line in sonnet_file: # note the new line character will be included in the line ... print(line, end='') When, in disgrace with fortune and men's eyes, I all alone beweep my outcast state, And trouble deaf heaven with my bootless cries, And look upon myself and curse my fate, Return to the Top Writing to Files>>> with open('bacon.txt', 'w') as bacon_file: ... bacon_file.write('Hello world!\n') 13 >>> with open('bacon.txt', 'a') as bacon_file: ... bacon_file.write('Bacon is not a vegetable.') 25 >>> with open('bacon.txt') as bacon_file: ... content = bacon_file.read() >>> print(content) Hello world! Bacon is not a vegetable. Return to the Top Saving Variables with the shelve Module To save variables:>>> import shelve >>> cats = ['Zophie', 'Pooka', 'Simon'] >>> with shelve.open('mydata') as shelf_file: ... shelf_file['cats'] = cats To open and read variables:>>> with shelve.open('mydata') as shelf_file: ... print(type(shelf_file)) ... print(shelf_file['cats']) <class 'shelve.DbfilenameShelf'> ['Zophie', 'Pooka', 'Simon'] Just like dictionaries, shelf values have keys() and values() methods that will return list-like values of the keys and values in the shelf. Since these methods return list-like values instead of true lists, you should pass them to the list() function to get them in list form.>>> with shelve.open('mydata') as shelf_file: ... print(list(shelf_file.keys())) ... print(list(shelf_file.values())) ['cats'] [['Zophie', 'Pooka', 'Simon']] Return to the Top Saving Variables with the pprint.pformat() Function>>> import pprint >>> cats = [{'name': 'Zophie', 'desc': 'chubby'}, {'name': 'Pooka', 'desc': 'fluffy'}] >>> pprint.pformat(cats) "[{'desc': 'chubby', 'name': 'Zophie'}, {'desc': 'fluffy', 'name': 'Pooka'}]" >>> with open('myCats.py', 'w') as file_obj: ... file_obj.write('cats = {}\n'.format(pprint.pformat(cats))) 83 Return to the Top Reading ZIP Files>>> import zipfile, os >>> os.chdir('C:\\') # move to the folder with example.zip >>> with zipfile.ZipFile('example.zip') as example_zip: ... print(example_zip.namelist()) ... spam_info = example_zip.getinfo('spam.txt') ... print(spam_info.file_size) ... print(spam_info.compress_size) ... print('Compressed file is %sx smaller!' % (round(spam_info.file_size / spam_info.compress_size, 2))) ['spam.txt', 'cats/', 'cats/catnames.txt', 'cats/zophie.jpg'] 13908 3828 'Compressed file is 3.63x smaller!' Return to the Top Extracting from ZIP Files The extractall() method for ZipFile objects extracts all the files and folders from a ZIP file into the current working directory.>>> import zipfile, os >>> os.chdir('C:\\') # move to the folder with example.zip >>> with zipfile.ZipFile('example.zip') as example_zip: ... example_zip.extractall() The extract() method for ZipFile objects will extract a single file from the ZIP file. Continue the interactive shell example:>>> with zipfile.ZipFile('example.zip') as example_zip: ... print(example_zip.extract('spam.txt')) ... print(example_zip.extract('spam.txt', 'C:\\some\\new\\folders')) 'C:\\spam.txt' 'C:\\some\\new\\folders\\spam.txt' Return to the Top Creating and Adding to ZIP Files>>> import zipfile >>> with zipfile.ZipFile('new.zip', 'w') as new_zip: ... new_zip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED) This code will create a new ZIP file named new.zip that has the compressed contents of spam.txt. Return to the Top JSON, YAML and configuration files JSON Open a JSON file with: import json with open("filename.json", "r") as f: content = json.loads(f.read()) Write a JSON file with: import json content = {"name": "Joe", "age": 20} with open("filename.json", "w") as f: f.write(json.dumps(content, indent=2)) Return to the Top YAML Compared to JSON, YAML allows for much better human maintainability and gives you the option to add comments. It is a convenient choice for configuration files where humans will have to edit it. There are two main libraries allowing to access to YAML files: PyYaml Ruamel.yaml Install them using pip install in your virtual environment. The first one it easier to use but the second one, Ruamel, implements much better the YAML specification, and allow for example to modify a YAML content without altering comments. Open a YAML file with: from ruamel.yaml import YAML with open("filename.yaml") as f: yaml=YAML() yaml.load(f) Return to the Top Anyconfig Anyconfig is a very handy package allowing to abstract completely the underlying configuration file format. It allows to load a Python dictionary from JSON, YAML, TOML, and so on. Install it with: pip install anyconfig Usage: import anyconfig conf1 = anyconfig.load("/path/to/foo/conf.d/a.yml") Return to the Top Debugging Raising Exceptions Exceptions are raised with a raise statement. In code, a raise statement consists of the following: The raise keyword A call to the Exception() function A string with a helpful error message passed to the Exception() function>>> raise Exception('This is the error message.') Traceback (most recent call last): File "<pyshell#191>", line 1, in <module> raise Exception('This is the error message.') Exception: This is the error message. Often it's the code that calls the function, not the function itself, that knows how to handle an exception. So you will commonly see a raise statement inside a function and the try and except statements in the code calling the function. def box_print(symbol, width, height): if len(symbol) != 1: raise Exception('Symbol must be a single character string.') if width <= 2: raise Exception('Width must be greater than 2.') if height <= 2: raise Exception('Height must be greater than 2.') print(symbol * width) for i in range(height - 2): print(symbol + (' ' * (width - 2)) + symbol) print(symbol * width) for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)): try: box_print(sym, w, h) except Exception as err: print('An exception happened: ' + str(err)) Return to the Top Getting the Traceback as a String The traceback is displayed by Python whenever a raised exception goes unhandled. But can also obtain it as a string by calling traceback.format_exc(). This function is useful if you want the information from an exception's traceback but also want an except statement to gracefully handle the exception. You will need to import Python's traceback module before calling this function.>>> import traceback >>> try: >>> raise Exception('This is the error message.') >>> except: >>> with open('errorInfo.txt', 'w') as error_file: >>> error_file.write(traceback.format_exc()) >>> print('The traceback info was written to errorInfo.txt.') 116 The traceback info was written to errorInfo.txt. The 116 is the return value from the write() method, since 116 characters were written to the file. The traceback text was written to errorInfo.txt. Traceback (most recent call last): File "<pyshell#28>", line 2, in <module> Exception: This is the error message. Return to the Top Assertions An assertion is a sanity check to make sure your code isn't doing something obviously wrong. These sanity checks are performed by assert statements. If the sanity check fails, then an AssertionError exception is raised. In code, an assert statement consists of the following: The assert keyword A condition (that is, an expression that evaluates to True or False) A comma A string to display when the condition is False>>> pod_bay_door_status = 'open' >>> assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' >>> pod_bay_door_status = 'I\'m sorry, Dave. I\'m afraid I can\'t do that.' >>> assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' AssertionError: The pod bay doors need to be "open". In plain English, an assert statement says, “I assert that this condition holds true, and if not, there is a bug somewhere in the program.” Unlike exceptions, your code should not handle assert statements with try and except; if an assert fails, your program should crash. By failing fast like this, you shorten the time between the original cause of the bug and when you first notice the bug. This will reduce the amount of code you will have to check before finding the code that's causing the bug. Disabling Assertions Assertions can be disabled by passing the -O option when running Python. Return to the Top Logging To enable the logging module to display log messages on your screen as your program runs, copy the following to the top of your program (but under the #! python shebang line): import logging logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s') Say you wrote a function to calculate the factorial of a number. In mathematics, factorial 4 is 1 × 2 × 3 × 4, or 24. Factorial 7 is 1 × 2 × 3 × 4 × 5 × 6 × 7, or 5,040. Open a new file editor window and enter the following code. It has a bug in it, but you will also enter several log messages to help yourself figure out what is going wrong. Save the program as factorialLog.py.>>> import logging >>> >>> logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s') >>> >>> logging.debug('Start of program') >>> >>> def factorial(n): >>> >>> logging.debug('Start of factorial(%s)' % (n)) >>> total = 1 >>> >>> for i in range(1, n + 1): >>> total *= i >>> logging.debug('i is ' + str(i) + ', total is ' + str(total)) >>> >>> logging.debug('End of factorial(%s)' % (n)) >>> >>> return total >>> >>> print(factorial(5)) >>> logging.debug('End of program') 2015-05-23 16:20:12,664 - DEBUG - Start of program 2015-05-23 16:20:12,664 - DEBUG - Start of factorial(5) 2015-05-23 16:20:12,665 - DEBUG - i is 0, total is 0 2015-05-23 16:20:12,668 - DEBUG - i is 1, total is 0 2015-05-23 16:20:12,670 - DEBUG - i is 2, total is 0 2015-05-23 16:20:12,673 - DEBUG - i is 3, total is 0 2015-05-23 16:20:12,675 - DEBUG - i is 4, total is 0 2015-05-23 16:20:12,678 - DEBUG - i is 5, total is 0 2015-05-23 16:20:12,680 - DEBUG - End of factorial(5) 0 2015-05-23 16:20:12,684 - DEBUG - End of program Return to the Top Logging Levels Logging levels provide a way to categorize your log messages by importance. There are five logging levels, described in Table 10-1 from least to most important. Messages can be logged at each level using a different logging function. Level Logging Function Description DEBUG logging.debug() The lowest level. Used for small details. Usually you care about these messages only when diagnosing problems. INFO logging.info() Used to record information on general events in your program or confirm that things are working at their point in the program. WARNING logging.warning() Used to indicate a potential problem that doesn't prevent the program from working but might do so in the future. ERROR logging.error() Used to record an error that caused the program to fail to do something. CRITICAL logging.critical() The highest level. Used to indicate a fatal error that has caused or is about to cause the program to stop running entirely. Return to the Top Disabling Logging After you've debugged your program, you probably don't want all these log messages cluttering the screen. The logging.disable() function disables these so that you don't have to go into your program and remove all the logging calls by hand.>>> import logging >>> logging.basicConfig(level=logging.INFO, format=' %(asctime)s -%(levelname)s - %(message)s') >>> logging.critical('Critical error! Critical error!') 2015-05-22 11:10:48,054 - CRITICAL - Critical error! Critical error! >>> logging.disable(logging.CRITICAL) >>> logging.critical('Critical error! Critical error!') >>> logging.error('Error! Error!') Return to the Top Logging to a File Instead of displaying the log messages to the screen, you can write them to a text file. The logging.basicConfig() function takes a filename keyword argument, like so: import logging logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') Return to the Top Lambda Functions This function:>>> def add(x, y): return x + y >>> add(5, 3) 8 Is equivalent to the lambda function:>>> add = lambda x, y: x + y >>> add(5, 3) 8 It's not even need to bind it to a name like add before:>>> (lambda x, y: x + y)(5, 3) 8 Like regular nested functions, lambdas also work as lexical closures:>>> def make_adder(n): return lambda x: x + n >>> plus_3 = make_adder(3) >>> plus_5 = make_adder(5) >>> plus_3(4) 7 >>> plus_5(4) 9 Note: lambda can only evaluate an expression, like a single line of code. Return to the Top Ternary Conditional Operator Many programming languages have a ternary operator, which define a conditional expression. The most common usage is to make a terse simple conditional assignment statement. In other words, it offers one-line code to evaluate the first expression if the condition is true, otherwise it evaluates the second expression.<expression1> if <condition> else <expression2> Example:>>> age = 15 >>> print('kid' if age < 18 else 'adult') kid Ternary operators can be chained:>>> age = 15 >>> print('kid' if age < 13 else 'teenager' if age < 18 else 'adult') teenager The code above is equivalent to: if age < 18: if age < 13: print('kid') else: print('teenager') else: print('adult') Return to the Top args and kwargs The names args and kwargs are arbitrary - the important thing are the * and ** operators. They can mean: In a function declaration, * means “pack all remaining positional arguments into a tuple named <name>”, while ** is the same for keyword arguments (except it uses a dictionary, not a tuple). In a function call, * means “unpack tuple or list named <name> to positional arguments at this position”, while ** is the same for keyword arguments. For example you can make a function that you can use to call any other function, no matter what parameters it has: def forward(f, *args, **kwargs): return f(*args, **kwargs) Inside forward, args is a tuple (of all positional arguments except the first one, because we specified it - the f), kwargs is a dict. Then we call f and unpack them so they become normal arguments to f. You use *args when you have an indefinite amount of positional arguments.>>> def fruits(*args): >>> for fruit in args: >>> print(fruit) >>> fruits("apples", "bananas", "grapes") "apples" "bananas" "grapes" Similarly, you use **kwargs when you have an indefinite number of keyword arguments.>>> def fruit(**kwargs): >>> for key, value in kwargs.items(): >>> print("{0}: {1}".format(key, value)) >>> fruit(name = "apple", color = "red") name: apple color: red >>> def show(arg1, arg2, *args, kwarg1=None, kwarg2=None, **kwargs): >>> print(arg1) >>> print(arg2) >>> print(args) >>> print(kwarg1) >>> print(kwarg2) >>> print(kwargs) >>> data1 = [1,2,3] >>> data2 = [4,5,6] >>> data3 = {'a':7,'b':8,'c':9} >>> show(*data1,*data2, kwarg1="python",kwarg2="cheatsheet",**data3) 1 2 (3, 4, 5, 6) python cheatsheet {'a': 7, 'b': 8, 'c': 9} >>> show(*data1, *data2, **data3) 1 2 (3, 4, 5, 6) None None {'a': 7, 'b': 8, 'c': 9} # If you do not specify ** for kwargs >>> show(*data1, *data2, *data3) 1 2 (3, 4, 5, 6, "a", "b", "c") None None {} Things to Remember(args) Functions can accept a variable number of positional arguments by using *args in the def statement. You can use the items from a sequence as the positional arguments for a function with the * operator. Using the * operator with a generator may cause your program to run out of memory and crash. Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs. Things to Remember(kwargs) Function arguments can be specified by position or by keyword. Keywords make it clear what the purpose of each argument is when it would be confusing with only positional arguments. Keyword arguments with default values make it easy to add new behaviors to a function, especially when the function has existing callers. Optional keyword arguments should always be passed by keyword instead of by position. Return to the Top Context Manager While Python's context managers are widely used, few understand the purpose behind their use. These statements, commonly used with reading and writing files, assist the application in conserving system memory and improve resource management by ensuring specific resources are only in use for certain processes. with statement A context manager is an object that is notified when a context (a block of code) starts and ends. You commonly use one with the with statement. It takes care of the notifying. For example, file objects are context managers. When a context ends, the file object is closed automatically:>>> with open(filename) as f: >>> file_contents = f.read() # the open_file object has automatically been closed. Anything that ends execution of the block causes the context manager's exit method to be called. This includes exceptions, and can be useful when an error causes you to prematurely exit from an open file or connection. Exiting a script without properly closing files/connections is a bad idea, that may cause data loss or other problems. By using a context manager you can ensure that precautions are always taken to prevent damage or loss in this way. Writing your own contextmanager using generator syntax It is also possible to write a context manager using generator syntax thanks to the contextlib.contextmanager decorator:>>> import contextlib >>> @contextlib.contextmanager ... def context_manager(num): ... print('Enter') ... yield num + 1 ... print('Exit') >>> with context_manager(2) as cm: ... # the following instructions are run when the 'yield' point of the context ... # manager is reached. ... # 'cm' will have the value that was yielded ... print('Right in the middle with cm = {}'.format(cm)) Enter Right in the middle with cm = 3 Exit >>> Return to the Top __main__ Top-level script environment __main__ is the name of the scope in which top-level code executes. A module's name is set equal to __main__ when read from standard input, a script, or from an interactive prompt. A module can discover whether or not it is running in the main scope by checking its own __name__, which allows a common idiom for conditionally executing code in a module when it is run as a script or with python -m but not when it is imported:>>> if __name__ == "__main__": ... # execute only if run as a script ... main() For a package, the same effect can be achieved by including a main.py module, the contents of which will be executed when the module is run with -m For example we are developing script which is designed to be used as module, we should do:>>> # Python program to execute function directly >>> def add(a, b): ... return a+b ... >>> add(10, 20) # we can test it by calling the function save it as calculate.py 30 >>> # Now if we want to use that module by importing we have to comment out our call, >>> # Instead we can write like this in calculate.py >>> if __name__ == "__main__": ... add(3, 5) ... >>> import calculate >>> calculate.add(3, 5) 8 Advantages Every Python module has it's __name__ defined and if this is __main__, it implies that the module is being run standalone by the user and we can do corresponding appropriate actions. If you import this script as a module in another script, the name is set to the name of the script/module. Python files can act as either reusable modules, or as standalone programs. if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported. Return to the Top setup.py The setup script is the centre of all activity in building, distributing, and installing modules using the Distutils. The main purpose of the setup script is to describe your module distribution to the Distutils, so that the various commands that operate on your modules do the right thing. The setup.py file is at the heart of a Python project. It describes all of the metadata about your project. There a quite a few fields you can add to a project to give it a rich set of metadata describing the project. However, there are only three required fields: name, version, and packages. The name field must be unique if you wish to publish your package on the Python Package Index (PyPI). The version field keeps track of different releases of the project. The packages field describes where you've put the Python source code within your project. This allows you to easily install Python packages. Often it's enough to write: python setup.py install and module will install itself. Our initial setup.py will also include information about the license and will re-use the README.txt file for the long_description field. This will look like:>>> from distutils.core import setup >>> setup( ... name='pythonCheatsheet', ... version='0.1', ... packages=['pipenv',], ... license='MIT', ... long_description=open('README.txt').read(), ... ) Find more information visit http://docs.python.org/install/index.html. Return to the Top Dataclasses Dataclasses are python classes but are suited for storing data objects. This module provides a decorator and functions for automatically adding generated special methods such as __init__() and __repr__() to user-defined classes. Features They store data and represent a certain data type. Ex: A number. For people familiar with ORMs, a model instance is a data object. It represents a specific kind of entity. It holds attributes that define or represent the entity. They can be compared to other objects of the same type. Ex: A number can be greater than, less than, or equal to another number. Python 3.7 provides a decorator dataclass that is used to convert a class into a dataclass. python 2.7>>> class Number: ... def __init__(self, val): ... self.val = val ... >>> obj = Number(2) >>> obj.val 2 with dataclass>>> @dataclass ... class Number: ... val: int ... >>> obj = Number(2) >>> obj.val 2 Return to the Top Default values It is easy to add default values to the fields of your data class.>>> @dataclass ... class Product: ... name: str ... count: int = 0 ... price: float = 0.0 ... >>> obj = Product("Python") >>> obj.name Python >>> obj.count 0 >>> obj.price 0.0 Type hints It is mandatory to define the data type in dataclass. However, If you don't want specify the datatype then, use typing.Any.>>> from dataclasses import dataclass >>> from typing import Any >>> @dataclass ... class WithoutExplicitTypes: ... name: Any ... value: Any = 42 ... Return to the Top Virtual Environment The use of a Virtual Environment is to test python code in encapsulated environments and to also avoid filling the base Python installation with libraries we might use for only one project. Return to the Top virtualenv Install virtualenv pip install virtualenv Install virtualenvwrapper-win (Windows) pip install virtualenvwrapper-win Usage: Make a Virtual Environment mkvirtualenv HelloWold Anything we install now will be specific to this project. And available to the projects we connect to this environment. Set Project Directory To bind our virtualenv with our current working directory we simply enter: setprojectdir . Deactivate To move onto something else in the command line type 'deactivate' to deactivate your environment. deactivate Notice how the parenthesis disappear. Workon Open up the command prompt and type 'workon HelloWold' to activate the environment and move into your root project folder workon HelloWold Return to the Top poetry Poetry is a tool for dependency management and packaging in Python. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you. Install Poetry pip install --user poetry Create a new project poetry new my-project This will create a my-project directory: my-project ├── pyproject.toml ├── README.rst ├── poetry_demo │ └── __init__.py └── tests ├── __init__.py └── test_poetry_demo.py The pyproject.toml file will orchestrate your project and its dependencies:[tool.poetry] name = "my-project" version = "0.1.0" description = "" authors = ["your name <your@mail.com>"] [tool.poetry.dependencies] python = "*" [tool.poetry.dev-dependencies] pytest = "^3.4" Packages To add dependencies to your project, you can specify them in the tool.poetry.dependencies section:[tool.poetry.dependencies] pendulum = "^1.4" Also, instead of modifying the pyproject.toml file by hand, you can use the add command and it will automatically find a suitable version constraint.$ poetry add pendulum To install the dependencies listed in the pyproject.toml: poetry install To remove dependencies: poetry remove pendulum For more information, check the documentation. Return to the Top pipenv Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. Windows is a first-class citizen, in our world. Install pipenv pip install pipenv Enter your Project directory and install the Packages for your project cd my_project pipenv install <package> Pipenv will install your package and create a Pipfile for you in your project's directory. The Pipfile is used to track which dependencies your project needs in case you need to re-install them. Uninstall Packages pipenv uninstall <package> Activate the Virtual Environment associated with your Python project pipenv shell Exit the Virtual Environment exit Find more information and a video in docs.pipenv.org. Return to the Top anaconda Anaconda is another popular tool to manage python packages. Where packages, notebooks, projects and environments are shared. Your place for free public conda package hosting. Usage: Make a Virtual Environment conda create -n HelloWorld To use the Virtual Environment, activate it by: conda activate HelloWorld Anything installed now will be specific to the project HelloWorld Exit the Virtual Environment conda deactivate Return to the Top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Python Cheat Sheet Lorem ipsum Python Cheat Sheet Python Basics Math Operators From Highest to Lowest precedence: Operators Operation Example** Exponent 2 ** 3 = 8% Modulus/Remaider 22 % 8 = 6// Integer division 22 // 8 = 2/ Division 22 / 8 = 2.75* Multiplication 3 * 3 = 9- Subtraction 5 - 2 = 3+ Addition 2 + 2 = 4 Examples of expressions in the interactive shell: 2 + 3 * 6 (2 + 3) * 6 2 ** 8 23 // 7 23 % 7 (5 - 1) * ((7 + 1) / (3 - 1)) Data Types Data Type Examples Integers-2, -1, 0, 1, 2, 3, 4, 5 Floating-point numbers-1.25, -1.0, --0.5, 0.0, 0.5, 1.0, 1.25 Strings'a', 'aa', 'aaa', 'Hello!', '11 cats' String Concatenation and Replication String concatenation:'Alice' 'Bob' Note: Avoid + operator for string concatenation. Prefer string formatting. String Replication:'Alice' * 5 Variables You can name a variable anything as long as it obeys the following three rules: It can be only one word. It can use only letters, numbers, and the underscore ( _) character. It can't begin with a number. Variable name starting with an underscore ( _) are considered as "unuseful`. Example: spam = 'Hello' _spam = 'Hello' _spam should not be used again in the code. Comments Inline comment:# This is a comment Multiline comment:# This is a # multiline comment Code with a comment: a = 1 # initialization Please note the two spaces in front of the comment. Function docstring: def foo(): """ This is a function docstring You can also use: ''' Function Docstring ''' """ The print Function print('Hello world!') a = 1 print('Hello world!', a) The input Function Example Code: print('What is your name?') # ask for their name myName = input() print('It is good to meet you, {}'.format(myName)) The len Function Evaluates to the integer value of the number of characters in a string: len('hello') Note: test of emptiness of strings, lists, dictionary, etc, should not use len, but prefer direct boolean evaluation. a = [1, 2, 3] if a: print("the list is not empty!") The str, int, and float Functions Integer to String or Float: str(29) print('I am {} years old.'.format(str(29))) str(-3.14) Float to Integer: int(7.7) int(7.7) + 1 Flow Control Comparison Operators Operator Meaning== Equal to!= Not equal to< Less than> Greater Than<= Less than or Equal to>= Greater than or Equal to These operators evaluate to True or False depending on the values you give them. Examples: 42 == 42 40 == 42 'hello' == 'hello' 'hello' == 'Hello' 'dog' != 'cat' 42 == 42.0 42 == '42' Boolean evaluation Never use == or != operator to evaluate boolean operation. Use the is or is not operators, or use implicit boolean evaluation. NO (even if they are valid Python): True == True True != False YES (even if they are valid Python): True is True True is not False These statements are equivalent: if a is True: pass if a is not False: pass if a: pass And these as well: if a is False: pass if a is not True: pass if not a: pass Boolean Operators There are three Boolean operators: and, or, and not. The and Operator's Truth Table: Expression Evaluates to True and True True True and False False False and True False False and False False The or Operator's Truth Table: Expression Evaluates to True or True True True or False True False or True True False or False False The not Operator's Truth Table: Expression Evaluates to not True False not False True Mixing Boolean and Comparison Operators(4 < 5) and (5 < 6) (4 < 5) and (9 < 6) (1 == 2) or (2 == 2) You can also use multiple Boolean operators in an expression, along with the comparison operators: 2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2 if Statements if name == 'Alice': print('Hi, Alice.') else Statements name = 'Bob' if name == 'Alice': print('Hi, Alice.') else: print('Hello, stranger.') elif Statements name = 'Bob' age = 5 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') name = 'Bob' age = 30 if name == 'Alice': print('Hi, Alice.') elif age < 12: print('You are not Alice, kiddo.') else: print('You are neither Alice nor a little kid.') while Loop Statements spam = 0 while spam < 5: print('Hello, world.') spam = spam + 1 break Statements If the execution reaches a break statement, it immediately exits the while loop's clause: while True: print('Please type your name.') name = input() if name == 'your name': break print('Thank you!') continue Statements When the program execution reaches a continue statement, the program execution immediately jumps back to the start of the loop. while True: print('Who are you?') name = input() if name != 'Joe': continue print('Hello, Joe. What is the password? (It is a fish.)') password = input() if password == 'swordfish': break print('Access granted.') for Loops and the range() Function print('My name is') for i in range(5): print('Jimmy Five Times ({})'.format(str(i))) The range() function can also be called with three arguments. The first two arguments will be the start and stop values, and the third will be the step argument. The step is the amount that the variable is increased by after each iteration. for i in range(0, 10, 2): print(i) You can even use a negative number for the step argument to make the for loop count down instead of up. for i in range(5, -1, -1): print(i) For else statement This allows to specify a statement to execute in case of the full loop has been executed. Only useful when a break condition can occur in the loop: for i in [1, 2, 3, 4, 5]: if i == 3: break else: print("only executed when no item of the list is equal to 3") Importing Modules import random for i in range(5): print(random.randint(1, 10)) import random, sys, os, math from random import *. Ending a Program with sys.exit import sys while True: print('Type exit to exit.') response = input() if response == 'exit': sys.exit() print('You typed {}.'.format(response)) Functions def hello(name): print('Hello {}'.format(name)) Return Values and return Statements When creating a function using the def statement, you can specify what the return value should be with a return statement. A return statement consists of the following: The return keyword. The value or expression that the function should return. import random def getAnswer(answerNumber): if answerNumber == 1: return 'It is certain' elif answerNumber == 2: return 'It is decidedly so' elif answerNumber == 3: return 'Yes' elif answerNumber == 4: return 'Reply hazy try again' elif answerNumber == 5: return 'Ask again later' elif answerNumber == 6: return 'Concentrate and ask again' elif answerNumber == 7: return 'My reply is no' elif answerNumber == 8: return 'Outlook not so good' elif answerNumber == 9: return 'Very doubtful' r = random.randint(1, 9) fortune = getAnswer(r) print(fortune) The None Value spam = print('Hello!') spam is None Note: never compare to None with the == operator. Always use is. print Keyword Arguments print('Hello', end='') print('World') print('cats', 'dogs', 'mice') print('cats', 'dogs', 'mice', sep=',') Local and Global Scope Code in the global scope cannot use any local variables. However, a local scope can access global variables. Code in a function's local scope cannot use variables in any other local scope. You can use the same name for different variables if they are in different scopes. That is, there can be a local variable named spam and a global variable also named spam. The global Statement If you need to modify a global variable from within a function, use the global statement: def spam(): global eggs eggs = 'spam' eggs = 'global' spam() print(eggs) There are four rules to tell whether a variable is in a local scope or global scope: If a variable is being used in the global scope (that is, outside of all functions), then it is always a global variable. If there is a global statement for that variable in a function, it is a global variable. Otherwise, if the variable is used in an assignment statement in the function, it is a local variable. But if the variable is not used in an assignment statement, it is a global variable. Exception Handling Basic exception handling def spam(divideBy): try: return 42 / divideBy except ZeroDivisionError as e: print('Error: Invalid argument: {}'.format(e)) print(spam(2)) print(spam(12)) print(spam(0)) print(spam(1)) Final code in exception handling Code inside the finally section is always executed, no matter if an exception has been raised or not, and even if an exception is not caught. def spam(divideBy): try: return 42 / divideBy except ZeroDivisionError as e: print('Error: Invalid argument: {}'.format(e)) finally: print("-- division finished --") print(spam(12)) print(spam(0)) Lists['cat', 'bat', 'rat', 'elephant'] Getting Individual Values in a List with Indexes spam = ['cat', 'bat', 'rat', 'elephant'] spam[0] spam[1] spam[2] spam[3] Negative Indexes spam = ['cat', 'bat', 'rat', 'elephant'] spam[-1] spam[-3] 'The {} is afraid of the {}.'.format(spam[-1], spam[-3]) Getting Sublists with Slices spam = ['cat', 'bat', 'rat', 'elephant'] spam[0:4] spam[1:3] spam[0:-1] spam = ['cat', 'bat', 'rat', 'elephant'] spam[:2] spam[1:] spam[:] Getting a list Length with len spam = ['cat', 'dog', 'moose'] len(spam) Changing Values in a List with Indexes spam = ['cat', 'bat', 'rat', 'elephant'] spam[1] = 'aardvark' spam spam[2] = spam[1] spam spam[-1] = 12345 spam List Concatenation and List Replication[1, 2, 3] + ['A', 'B', 'C'] ['X', 'Y', 'Z'] * 3 spam = [1, 2, 3] spam = spam + ['A', 'B', 'C'] spam Removing Values from Lists with del Statements spam = ['cat', 'bat', 'rat', 'elephant'] del spam[2] spam del spam[2] spam Using for Loops with Lists supplies = ['pens', 'staplers', 'flame-throwers', 'binders'] for i, supply in enumerate(supplies): print('Index {} in supplies is: {}'.format(str(i), supply)) Looping Through Multiple Lists with zip name = ['Pete', 'John', 'Elizabeth'] age = [6, 23, 44] for n, a in zip(name, age): print('{} is {} years old'.format(n, a)) The in and not in Operators'howdy' in ['hello', 'hi', 'howdy', 'heyas'] spam = ['hello', 'hi', 'howdy', 'heyas'] False 'howdy' not in spam 'cat' not in spam The Multiple Assignment Trick The multiple assignment trick is a shortcut that lets you assign multiple variables with the values in a list in one line of code. So instead of doing this: cat = ['fat', 'orange', 'loud'] size = cat[0] color = cat[1] disposition = cat[2] You could type this line of code: cat = ['fat', 'orange', 'loud'] size, color, disposition = cat The multiple assignment trick can also be used to swap the values in two variables: a, b = 'Alice', 'Bob' a, b = b, a print(a) print(b) Augmented Assignment Operators Operator Equivalent spam += 1 spam = spam + 1 spam -= 1 spam = spam - 1 spam *= 1 spam = spam * 1 spam /= 1 spam = spam / 1 spam %= 1 spam = spam % 1 Examples: spam = 'Hello' spam += ' world!' spam bacon = ['Zophie'] bacon *= 3 bacon Finding a Value in a List with the index Method spam = ['Zophie', 'Pooka', 'Fat-tail', 'Pooka'] spam.index('Pooka') Adding Values to Lists with append and insert append(): spam = ['cat', 'dog', 'bat'] spam.append('moose') spam insert(): spam = ['cat', 'dog', 'bat'] spam.insert(1, 'chicken') spam Removing Values from Lists with remove spam = ['cat', 'bat', 'rat', 'elephant'] spam.remove('bat') spam If the value appears multiple times in the list, only the first instance of the value will be removed. Sorting the Values in a List with sort spam = [2, 5, 3.14, 1, -7] spam.sort() spam spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants'] spam.sort() spam You can also pass True for the reverse keyword argument to have sort() sort the values in reverse order: spam.sort(reverse=True) spam If you need to sort the values in regular alphabetical order, pass str. lower for the key keyword argument in the sort() method call: spam = ['a', 'z', 'A', 'Z'] spam.sort(key=str.lower) spam You can use the built-in function sorted to return a new list: spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants'] sorted(spam) Tuple Data Type eggs = ('hello', 42, 0.5) eggs[0] eggs[1:3] len(eggs) The main way that tuples are different from lists is that tuples, like strings, are immutable. Converting Types with the list and tuple Functions tuple(['cat', 'dog', 5]) list(('cat', 'dog', 5)) list('hello') Dictionaries and Structuring Data Example Dictionary: myCat = {'size': 'fat', 'color': 'gray', 'disposition': 'loud'} The keys, values, and items Methods values(): spam = {'color': 'red', 'age': 42} for v in spam.values(): print(v) keys(): for k in spam.keys(): print(k) items(): for i in spam.items(): print(i) Using the keys(), values(), and items() methods, a for loop can iterate over the keys, values, or key-value pairs in a dictionary, respectively. spam = {'color': 'red', 'age': 42} for k, v in spam.items(): print('Key: {} Value: {}'.format(k, str(v))) Checking if a Key or Value Exists in a Dictionary spam = {'name': 'Zophie', 'age': 7} 'name' in spam.keys() 'Zophie' in spam.values() # You can omit the call to keys() when checking for a key 'color' in spam 'color' not in spam 'color' in spam The get Method picnic_items = {'apples': 5, 'cups': 2} 'I am bringing {} cups.'.format(str(picnic_items.get('cups', 0))) 'I am bringing {} eggs.'.format(str(picnic_items.get('eggs', 0))) The setdefault Method Let's consider this code: spam = {'name': 'Pooka', 'age': 5} if 'color' not in spam: spam['color'] = 'black' Using setdefault we could make the same code more shortly: spam = {'name': 'Pooka', 'age': 5} spam.setdefault('color', 'black') spam spam.setdefault('color', 'white') spam Pretty Printing import pprint message = 'It was a bright cold day in April, and the clocks were striking thirteen.' count = {} for character in message: count.setdefault(character, 0) count[character] = count[character] + 1 pprint.pprint(count) Merge two dictionaries# in Python 3.5+: x = {'a': 1, 'b': 2} y = {'b': 3, 'c': 4} z = {**x, **y} z sets From the Python 3 documentation A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference. Initializing a set There are two ways to create sets: using curly braces {} and the bult-in function set() s = {1, 2, 3} s = set([1, 2, 3]) When creating an empty set, be sure to not use the curly braces {} or you will get an empty dictionary instead. s = {} type(s) sets: unordered collections of unique elements A set automatically remove all the duplicate values. s = {1, 2, 3, 2, 3, 4} s And as an unordered data type, they can't be indexed. s = {1, 2, 3} s(0) set add and update Using the add() method we can add a single element to the set. s = {1, 2, 3} s.add(4) s And with update(), multiple ones . s = {1, 2, 3} s.update([2, 3, 4, 5, 6]) s # remember, sets automatically remove duplicates set remove and discard Both methods will remove an element from the set, but remove() will raise a key error if the value doesn't exist. s = {1, 2, 3} s.remove(3) s s.remove(3) discard() won't raise any errors. s = {1, 2, 3} s.discard(3) s s.discard(3) set union union() or | will create a new set that contains all the elements from the sets provided. s1 = {1, 2, 3} s2 = {3, 4, 5} s1.union(s2) # or 's1 | s2' set intersection intersection or & will return a set containing only the elements that are common to all of them. s1 = {1, 2, 3} s2 = {2, 3, 4} s3 = {3, 4, 5} s1.intersection(s2, s3) # or 's1 & s2 & s3' set difference difference or - will return only the elements that are in one of the sets. s1 = {1, 2, 3} s2 = {2, 3, 4} s1.difference(s2) # or 's1 - s2' set symetric_difference symetric_difference or ^ will return all the elements that are not common between them. s1 = {1, 2, 3} s2 = {2, 3, 4} s1.symmetric_difference(s2) # or 's1 ^ s2' itertools Module The itertools module is a collection of tools intented to be fast and use memory efficiently when handling iterators (like lists or dictionaries). From the official Python 3.x documentation: The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python. The itertools module comes in the standard library and must be imported. The operator module will also be used. This module is not necessary when using itertools, but needed for some of the examples below. import itertools import operator accumulate Makes an iterator that returns the results of a function. itertools.accumulate(iterable[, func]) Example: data = [1, 2, 3, 4, 5] result = itertools.accumulate(data, operator.mul) for each in result: print(each) The operator.mul takes two numbers and multiplies them: operator.mul(1, 2) operator.mul(2, 3) operator.mul(6, 4) operator.mul(24, 5) Passing a function is optional: data = [5, 2, 6, 4, 5, 9, 1] result = itertools.accumulate(data) for each in result: print(each) If no function is designated the items will be summed: 5 5 + 2 = 7 7 + 6 = 13 13 + 4 = 17 17 + 5 = 22 22 + 9 = 31 31 + 1 = 32 combinations Takes an iterable and a integer. This will create all the unique combination that have r members. itertools.combinations(iterable, r) Example: shapes = ['circle', 'triangle', 'square',] result = itertools.combinations(shapes, 2) for each in result: print(each) combinations with replacement Just like combinations(), but allows individual elements to be repeated more than once. itertools.combinations_with_replacement(iterable, r) Example: shapes = ['circle', 'triangle', 'square'] result = itertools.combinations_with_replacement(shapes, 2) for each in result: print(each) count Makes an iterator that returns evenly spaced values starting with number start. itertools.count(start=0, step=1) Example: for i in itertools.count(10,3): print(i) if i > 20: break cycle This function cycles through an iterator endlessly. itertools.cycle(iterable) Example: colors = ['red', 'orange', 'yellow', 'green', 'blue', 'violet'] for color in itertools.cycle(colors): print(color) When reached the end of the iterable it start over again from the beginning. chain Take a series of iterables and return them as one long iterable. itertools.chain(*iterables) Example: colors = ['red', 'orange', 'yellow', 'green', 'blue'] shapes = ['circle', 'triangle', 'square', 'pentagon'] result = itertools.chain(colors, shapes) for each in result: print(each) compress Filters one iterable with another. itertools.compress(data, selectors) Example: shapes = ['circle', 'triangle', 'square', 'pentagon'] selections = [True, False, True, False] result = itertools.compress(shapes, selections) for each in result: print(each) dropwhile Make an iterator that drops elements from the iterable as long as the predicate is true; afterwards, returns every element. itertools.dropwhile(predicate, iterable) Example: data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1] result = itertools.dropwhile(lambda x: x<5, data) for each in result: print(each) filterfalse Makes an iterator that filters elements from iterable returning only those for which the predicate is False. itertools.filterfalse(predicate, iterable) Example: data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] result = itertools.filterfalse(lambda x: x<5, data) for each in result: print(each) groupby Simply put, this function groups things together. itertools.groupby(iterable, key=None) Example: robots = [{ 'name': 'blaster', 'faction': 'autobot' }, { 'name': 'galvatron', 'faction': 'decepticon' }, { 'name': 'jazz', 'faction': 'autobot' }, { 'name': 'metroplex', 'faction': 'autobot' }, { 'name': 'megatron', 'faction': 'decepticon' }, { 'name': 'starcream', 'faction': 'decepticon' }] for key, group in itertools.groupby(robots, key=lambda x: x['faction']): print(key) print(list(group)) islice This function is very much like slices. This allows you to cut out a piece of an iterable. itertools.islice(iterable, start, stop[, step]) Example: colors = ['red', 'orange', 'yellow', 'green', 'blue',] few_colors = itertools.islice(colors, 2) for each in few_colors: print(each) permutations itertools.permutations(iterable, r=None) Example: alpha_data = ['a', 'b', 'c'] result = itertools.permutations(alpha_data) for each in result: print(each) product Creates the cartesian products from a series of iterables. num_data = [1, 2, 3] alpha_data = ['a', 'b', 'c'] result = itertools.product(num_data, alpha_data) for each in result: print(each) repeat This function will repeat an object over and over again. Unless, there is a times argument. itertools.repeat(object[, times]) Example: for i in itertools.repeat("spam", 3): print(i) starmap Makes an iterator that computes the function using arguments obtained from the iterable. itertools.starmap(function, iterable) Example: data = [(2, 6), (8, 4), (7, 3)] result = itertools.starmap(operator.mul, data) for each in result: print(each) takewhile The opposite of dropwhile(). Makes an iterator and returns elements from the iterable as long as the predicate is true. itertools.takewhile(predicate, iterable) Example: data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1] result = itertools.takewhile(lambda x: x<5, data) for each in result: print(each) tee Return n independent iterators from a single iterable. itertools.tee(iterable, n=2) Example: colors = ['red', 'orange', 'yellow', 'green', 'blue'] alpha_colors, beta_colors = itertools.tee(colors) for each in alpha_colors: print(each) colors = ['red', 'orange', 'yellow', 'green', 'blue'] alpha_colors, beta_colors = itertools.tee(colors) for each in beta_colors: print(each) zip_longest Makes an iterator that aggregates elements from each of the iterables. If the iterables are of uneven length, missing values are filled-in with fillvalue. Iteration continues until the longest iterable is exhausted. itertools.zip_longest(*iterables, fillvalue=None) Example: colors = ['red', 'orange', 'yellow', 'green', 'blue',] data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,] for each in itertools.zip_longest(colors, data, fillvalue=None): print(each) Comprehensions List comprehension a = [1, 3, 5, 7, 9, 11] [i - 1 for i in a] Set comprehension b = {"abc", "def"} {s.upper() for s in b} Dict comprehension c = {'name': 'Pooka', 'age': 5} {v, k for k, v in c.items()} A List comprehension can be generated from a dictionary: c = {'name': 'Pooka', 'first_name': 'Oooka'} ["{}:{}".format(k.upper(), v.upper()) for k, v in c.items()] Manipulating Strings Escape Characters Escape character Prints as\' Single quote\" Double quote\t Tab\n Newline (line break)\\ Backslash Example: print("Hello there!\nHow are you?\nI\'m doing fine.") Hello there! How are you? Raw Strings A raw string completely ignores all escape characters and prints any backslash that appears in the string. print(r'That is Carol\'s cat.') Note: mostly used for regular expression definition (see re package) Multiline Strings with Triple Quotes print('''Dear Alice, Eve's cat has been arrested for catnapping, cat burglary, and extortion. Sincerely, Bob''') To keep a nicer flow in your code, you can use the dedent function from the textwrap standard package. from textwrap import dedent def my_function(): print(''' Dear Alice, Eve's cat has been arrested for catnapping, cat burglary, and extortion. Sincerely, Bob ''').strip() This generates the same string than before. Indexing and Slicing Strings H e l l o w o r l d ! 0 1 2 3 4 5 6 7 8 9 10 11 spam = 'Hello world!' spam[0] spam[4] spam[-1] Slicing: spam[0:5] spam[:5] spam[6:] spam[6:-1] spam[:-1] spam[::-1] spam = 'Hello world!' fizz = spam[0:5] fizz The in and not in Operators with Strings'Hello' in 'Hello World' 'Hello' in 'Hello' 'HELLO' in 'Hello World' '' in 'spam' 'cats' not in 'cats and dogs' The in and not in Operators with list a = [1, 2, 3, 4] 5 in a 2 in a The upper, lower, isupper, and islower String Methods upper() and lower(): spam = 'Hello world!' spam = spam.upper() spam spam = spam.lower() spam isupper() and islower(): spam = 'Hello world!' spam.islower() spam.isupper() 'HELLO'.isupper() 'abc12345'.islower() '12345'.islower() '12345'.isupper() The isX String Methods isalpha() returns True if the string consists only of letters and is not blank. isalnum() returns True if the string consists only of lettersand numbers and is not blank. isdecimal() returns True if the string consists only ofnumeric characters and is not blank. isspace() returns True if the string consists only of spaces,tabs, and new-lines and is not blank. istitle() returns True if the string consists only of wordsthat begin with an uppercase letter followed by onlylowercase letters. The startswith and endswith String Methods'Hello world!'.startswith('Hello') 'Hello world!'.endswith('world!') 'abc123'.startswith('abcdef') 'abc123'.endswith('12') 'Hello world!'.startswith('Hello world!') 'Hello world!'.endswith('Hello world!') The join and split String Methods join():', '.join(['cats', 'rats', 'bats']) ' '.join(['My', 'name', 'is', 'Simon']) 'ABC'.join(['My', 'name', 'is', 'Simon']) split():'My name is Simon'.split() 'MyABCnameABCisABCSimon'.split('ABC') 'My name is Simon'.split('m') Justifying Text with rjust, ljust, and center rjust() and ljust():'Hello'.rjust(10) 'Hello'.rjust(20) 'Hello World'.rjust(20) 'Hello'.ljust(10) An optional second argument to rjust() and ljust() will specify a fill character other than a space character. Enter the following into the interactive shell:'Hello'.rjust(20, '*') 'Hello'.ljust(20, '-') center():'Hello'.center(20) 'Hello'.center(20, '=') Removing Whitespace with strip, rstrip, and lstrip spam = ' Hello World ' spam.strip() spam.lstrip() spam.rstrip() spam = 'SpamSpamBaconSpamEggsSpamSpam' spam.strip('ampS') Copying and Pasting Strings with the pyperclip Module First, install pypeerclip with pip: pip install pyperclip import pyperclip pyperclip.copy('Hello world!') pyperclip.paste() String Formatting% operator name = 'Pete' 'Hello %s' % name We can use the %x format specifier to convert an int value to a string: num = 5 'I have %x apples' % num Note: For new code, using str.format or f-strings is strongly recommended over the % operator. str.format Python 3 introduced a new way to do string formatting that was later back-ported to Python 2.7. This makes the syntax for string formatting more regular. name = 'John' age = 20' "Hello I'm {}, my age is {}".format(name, age) "Hello I'm {0}, my age is {1}".format(name, age) The official Python 3.x documentation recommend str.format over the % operator: The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text. Lazy string formatting You would only use %s string formatting on functions that can do lazy parameters evaluation, the most common being logging: Prefer: name = "alice" logging.debug("User name: %s", name) Over: logging.debug("User name: {}".format(name)) Or: logging.debug("User name: " + name) Formatted String Literals or f-strings Python 3.6+ name = 'Elizabeth' f'Hello {name}!' It is even possible to do inline arithmetic with it: a = 5 b = 10 f'Five plus ten is {a + b} and not {2 * (a + b)}.' Template Strings A simpler and less powerful mechanism, but it is recommended when handling format strings generated by users. Due to their reduced complexity template strings are a safer choice. from string import Template name = 'Elizabeth' t = Template('Hey $name!') t.substitute(name=name) Regular Expressions Import the regex module with import re. Create a Regex object with the re.compile() function. (Remember to use a raw string.) Pass the string you want to search into the Regex object's search() method. This returns a Match object. Call the Match object's group() method to return a string of the actual matched text. All the regex functions in Python are in the re module: import re Matching Regex Objects phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') mo = phone_num_regex.search('My number is 415-555-4242.') print('Phone number found: {}'.format(mo.group())) Grouping with Parentheses phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') mo = phone_num_regex.search('My number is 415-555-4242.') mo.group(1) mo.group(2) mo.group(0) mo.group() To retrieve all the groups at once: use the groups() method—note the plural form for the name. mo.groups() area_code, main_number = mo.groups() print(area_code) print(main_number) Matching Multiple Groups with the Pipe The | character is called a pipe. You can use it anywhere you want to match one of many expressions. For example, the regular expression r'Batman|Tina Fey' will match either 'Batman' or 'Tina Fey'. hero_regex = re.compile (r'Batman|Tina Fey') mo1 = hero_regex.search('Batman and Tina Fey.') mo1.group() mo2 = hero_regex.search('Tina Fey and Batman.') mo2.group() You can also use the pipe to match one of several patterns as part of your regex: bat_regex = re.compile(r'Bat(man|mobile|copter|bat)') mo = bat_regex.search('Batmobile lost a wheel') mo.group() mo.group(1) Optional Matching with the Question Mark The ? character flags the group that precedes it as an optional part of the pattern. bat_regex = re.compile(r'Bat(wo)?man') mo1 = bat_regex.search('The Adventures of Batman') mo1.group() mo2 = bat_regex.search('The Adventures of Batwoman') mo2.group() Matching Zero or More with the Star The * (called the star or asterisk) means “match zero or more”—the group that precedes the star can occur any number of times in the text. bat_regex = re.compile(r'Bat(wo)*man') mo1 = bat_regex.search('The Adventures of Batman') mo1.group() mo2 = bat_regex.search('The Adventures of Batwoman') mo2.group() mo3 = bat_regex.search('The Adventures of Batwowowowoman') mo3.group() Matching One or More with the Plus While * means “match zero or more,” the + (or plus) means “match one or more”. The group preceding a plus must appear at least once. It is not optional: bat_regex = re.compile(r'Bat(wo)+man') mo1 = bat_regex.search('The Adventures of Batwoman') mo1.group() mo2 = bat_regex.search('The Adventures of Batwowowowoman') mo2.group() mo3 = bat_regex.search('The Adventures of Batman') mo3 is None Matching Specific Repetitions with Curly Brackets If you have a group that you want to repeat a specific number of times, follow the group in your regex with a number in curly brackets. For example, the regex (Ha){3} will match the string 'HaHaHa', but it will not match 'HaHa', since the latter has only two repeats of the (Ha) group. Instead of one number, you can specify a range by writing a minimum, a comma, and a maximum in between the curly brackets. For example, the regex (Ha){3,5} will match 'HaHaHa', 'HaHaHaHa', and 'HaHaHaHaHa'. ha_regex = re.compile(r'(Ha){3}') mo1 = ha_regex.search('HaHaHa') mo1.group() mo2 = ha_regex.search('Ha') mo2 is None Greedy and Nongreedy Matching Python's regular expressions are greedy by default, which means that in ambiguous situations they will match the longest string possible. The non-greedy version of the curly brackets, which matches the shortest string possible, has the closing curly bracket followed by a question mark. greedy_ha_regex = re.compile(r'(Ha){3,5}') mo1 = greedy_ha_regex.search('HaHaHaHaHa') mo1.group() nongreedy_ha_regex = re.compile(r'(Ha){3,5}?') mo2 = nongreedy_ha_regex.search('HaHaHaHaHa') mo2.group() The findall Method In addition to the search() method, Regex objects also have a findall() method. While search() will return a Match object of the first matched text in the searched string, the findall() method will return the strings of every match in the searched string. phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups phone_num_regex.findall('Cell: 415-555-9999 Work: 212-555-0000') To summarize what the findall() method returns, remember the following: When called on a regex with no groups, such as \d-\d\d\d-\d\d\d\d, the method findall() returns a list of ng matches, such as ['415-555-9999', '212-555-0000']. When called on a regex that has groups, such as (\d\d\d)-d\d)-(\d\ d\d\d), the method findall() returns a list of es of strings (one string for each group), such as [('415', ', '9999'), ('212', '555', '0000')]. Making Your Own Character Classes There are times when you want to match a set of characters but the shorthand character classes (\d, \w, \s, and so on) are too broad. You can define your own character class using square brackets. For example, the character class [aeiouAEIOU] will match any vowel, both lowercase and uppercase. vowel_regex = re.compile(r'[aeiouAEIOU]') vowel_regex.findall('Robocop eats baby food. BABY FOOD.') You can also include ranges of letters or numbers by using a hyphen. For example, the character class [a-zA-Z0-9] will match all lowercase letters, uppercase letters, and numbers. By placing a caret character (^) just after the character class's opening bracket, you can make a negative character class. A negative character class will match all the characters that are not in the character class. For example, enter the following into the interactive shell: consonant_regex = re.compile(r'[^aeiouAEIOU]') consonant_regex.findall('Robocop eats baby food. BABY FOOD.') The Caret and Dollar Sign Characters You can also use the caret symbol (^) at the start of a regex to indicate that a match must occur at the beginning of the searched text. Likewise, you can put a dollar sign ($) at the end of the regex to indicate the string must end with this regex pattern. And you can use the ^ and $ together to indicate that the entire string must match the regex—that is, it's not enough for a match to be made on some subset of the string. The r'^Hello' regular expression string matches strings that begin with 'Hello': begins_with_hello = re.compile(r'^Hello') begins_with_hello.search('Hello world!') begins_with_hello.search('He said hello.') is None The r'\d$' regular expression string matches strings that end with a numeric character from 0 to 9: whole_string_is_num = re.compile(r'^\d+$') whole_string_is_num.search('1234567890') whole_string_is_num.search('12345xyz67890') is None whole_string_is_num.search('12 34567890') is None The Wildcard Character The . (or dot) character in a regular expression is called a wildcard and will match any character except for a newline: at_regex = re.compile(r'.at') at_regex.findall('The cat in the hat sat on the flat mat.') Matching Everything with Dot-Star name_regex = re.compile(r'First Name: (.*) Last Name: (.*)') mo = name_regex.search('First Name: Some Last Name: One') mo.group(1) mo.group(2) The dot-star uses greedy mode: It will always try to match as much text as possible. To match any and all text in a nongreedy fashion, use the dot, star, and question mark (.*?). The question mark tells Python to match in a nongreedy way: nongreedy_regex = re.compile(r'<.*?>') mo = nongreedy_regex.search('<To serve man> for dinner.>') mo.group() greedy_regex = re.compile(r'<.*>') mo = greedy_regex.search('<To serve man> for dinner.>') mo.group() Matching Newlines with the Dot Character The dot-star will match everything except a newline. By passing re.DOTALL as the second argument to re.compile(), you can make the dot character match all characters, including the newline character: no_newline_regex = re.compile('.*') no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() newline_regex = re.compile('.*', re.DOTALL) newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group() Review of Regex Symbols Symbol Matches? zero or one of the preceding group.* zero or more of the preceding group.+ one or more of the preceding group.{n} exactly n of the preceding group.{n,} n or more of the preceding group.{,m} 0 to m of the preceding group.{n,m} at least n and at most m of the preceding p.{n,m}? or *? or +? performs a nongreedy match of the preceding p.^spam means the string must begin with spam. spam$ means the string must end with spam.. any character, except newline characters.\d, \w, and \s a digit, word, or space character, resectively.\D, \W, and \S anything except a digit, word, or space acter, respectively.[abc] any character between the brackets (such as a, b, ).[^abc] any character that isn't between the brackets. Case-Insensitive Matching To make your regex case-insensitive, you can pass re.IGNORECASE or re.I as a second argument to re.compile(): robocop = re.compile(r'robocop', re.I) robocop.search('Robocop is part man, part machine, all cop.').group() robocop.search('ROBOCOP protects the innocent.').group() robocop.search('Al, why does your programming book talk about robocop so much?').group() Substituting Strings with the sub() Method The sub() method for Regex objects is passed two arguments: The first argument is a string to replace any matches. The second is the string for the regular expression. The sub() method returns a string with the substitutions applied: names_regex = re.compile(r'Agent \w+') names_regex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.') Another example: agent_names_regex = re.compile(r'Agent (\w)\w*') agent_names_regex.sub(r'\1****', 'Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.') Managing Complex Regexes To tell the re.compile() function to ignore whitespace and comments inside the regular expression string, “verbose mode” can be enabled by passing the variable re.VERBOSE as the second argument to re.compile(). Now instead of a hard-to-read regular expression like this: phone_regex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)') you can spread the regular expression over multiple lines with comments like this: phone_regex = re.compile(r'''( (\d{3}|\(\d{3}\))? # area code (\s|-|\.)? # separator \d{3} # first 3 digits (\s|-|\.) # separator \d{4} # last 4 digits (\s*(ext|x|ext.)\s*\d{2,5})? # extension )''', re.VERBOSE) Handling File and Directory Paths There are two main modules in Python that deals with path manipulation. One is the os.path module and the other is the pathlib module. The pathlib module was added in Python 3.4, offering an object-oriented way to handle file system paths. Backslash on Windows and Forward Slash on OS X and Linux On Windows, paths are written using backslashes () as the separator between folder names. On Unix based operating system such as macOS, Linux, and BSDs, the forward slash (/) is used as the path separator. Joining paths can be a headache if your code needs to work on different platforms. Fortunately, Python provides easy ways to handle this. We will showcase how to deal with this with both os.path.join and pathlib.Path.joinpath Using os.path.join on Windows: import os os.path.join('usr', 'bin', 'spam') And using pathlib on *nix: from pathlib import Path print(Path('usr').joinpath('bin').joinpath('spam')) pathlib also provides a shortcut to joinpath using the / operator: from pathlib import Path print(Path('usr') / 'bin' / 'spam') Notice the path separator is different between Windows and Unix based operating system, that's why you want to use one of the above methods instead of adding strings together to join paths together. Joining paths is helpful if you need to create different file paths under the same directory. Using os.path.join on Windows: my_files = ['accounts.txt', 'details.csv', 'invite.docx'] for filename in my_files: print(os.path.join('C:\\Users\\asweigart', filename)) Using pathlib on *nix: my_files = ['accounts.txt', 'details.csv', 'invite.docx'] home = Path.home() for filename in my_files: print(home / filename) The Current Working Directory Using os on Windows: import os os.getcwd() os.chdir('C:\\Windows\\System32') os.getcwd() Using pathlib on *nix: from pathlib import Path from os import chdir print(Path.cwd()) chdir('/usr/lib/python3.6') print(Path.cwd()) Creating New Folders Using os on Windows: import os os.makedirs('C:\\delicious\\walnut\\waffles') Using pathlib on *nix: from pathlib import Path cwd = Path.cwd() (cwd / 'delicious' / 'walnut' / 'waffles').mkdir() Oh no, we got a nasty error! The reason is that the 'delicious' directory does not exist, so we cannot make the 'walnut' and the 'waffles' directories under it. To fix this, do: from pathlib import Path cwd = Path.cwd() (cwd / 'delicious' / 'walnut' / 'waffles').mkdir(parents=True) And all is good :) Absolute vs. Relative Paths There are two ways to specify a file path. An absolute path, which always begins with the root folder A relative path, which is relative to the program's current working directory There are also the dot (.) and dot-dot (..) folders. These are not real folders but special names that can be used in a path. A single period (“dot”) for a folder name is shorthand for “this directory.” Two periods (“dot-dot”) means “the parent folder.” Handling Absolute and Relative Paths To see if a path is an absolute path: Using os.path on *nix: import os os.path.isabs('/') os.path.isabs('..') Using pathlib on *nix: from pathlib import Path Path('/').is_absolute() Path('..').is_absolute() You can extract an absolute path with both os.path and pathlib Using os.path on *nix: import os os.getcwd() os.path.abspath('..') Using pathlib on *nix: from pathlib import Path print(Path.cwd()) print(Path('..').resolve()) You can get a relative path from a starting path to another path. Using os.path on *nix: import os os.path.relpath('/etc/passwd', '/') Using pathlib on *nix: from pathlib import Path print(Path('/etc/passwd').relative_to('/')) Checking Path Validity Checking if a file/directory exists: Using os.path on *nix: import os os.path.exists('.') os.path.exists('setup.py') os.path.exists('/etc') os.path.exists('nonexistentfile') Using pathlib on *nix: from pathlib import Path Path('.').exists() Path('setup.py').exists() Path('/etc').exists() Path('nonexistentfile').exists() Checking if a path is a file: Using os.path on *nix: import os os.path.isfile('setup.py') os.path.isfile('/home') os.path.isfile('nonexistentfile') Using pathlib on *nix: from pathlib import Path Path('setup.py').is_file() Path('/home').is_file() Path('nonexistentfile').is_file() Checking if a path is a directory: Using os.path on *nix: import os os.path.isdir('/') os.path.isdir('setup.py') os.path.isdir('/spam') Using pathlib on *nix: from pathlib import Path Path('/').is_dir() Path('setup.py').is_dir() Path('/spam').is_dir() Finding File Sizes and Folder Contents Getting a file's size in bytes: Using os.path on Windows: import os os.path.getsize('C:\\Windows\\System32\\calc.exe') Using pathlib on *nix: from pathlib import Path stat = Path('/bin/python3.6').stat() print(stat) # stat contains some other information about the file as well print(stat.st_size) # size in bytes Listing directory contents using os.listdir on Windows: import os os.listdir('C:\\Windows\\System32') Listing directory contents using pathlib on *nix: from pathlib import Path for f in Path('/usr/bin').iterdir(): print(f) To find the total size of all the files in this directory: WARNING: Directories themselves also have a size! So you might want to check for whether a path is a file or directory using the methods in the methods discussed in the above section! Using os.path.getsize() and os.listdir() together on Windows: import os total_size = 0 for filename in os.listdir('C:\\Windows\\System32'): total_size = total_size + os.path.getsize(os.path.join('C:\\Windows\\System32', filename)) print(total_size) Using pathlib on *nix: from pathlib import Path total_size = 0 for sub_path in Path('/usr/bin').iterdir(): total_size += sub_path.stat().st_size print(total_size) Copying Files and Folders The shutil module provides functions for copying files, as well as entire folders. import shutil, os os.chdir('C:\\') shutil.copy('C:\\spam.txt', 'C:\\delicious') shutil.copy('eggs.txt', 'C:\\delicious\\eggs2.txt') 'C:\\delicious\\eggs2.txt' While shutil.copy() will copy a single file, shutil.copytree() will copy an entire folder and every folder and file contained in it: import shutil, os os.chdir('C:\\') shutil.copytree('C:\\bacon', 'C:\\bacon_backup') Moving and Renaming Files and Folders import shutil shutil.move('C:\\bacon.txt', 'C:\\eggs') The destination path can also specify a filename. In the following example, the source file is moved and renamed: shutil.move('C:\\bacon.txt', 'C:\\eggs\\new_bacon.txt') If there is no eggs folder, then move() will rename bacon.txt to a file named eggs. shutil.move('C:\\bacon.txt', 'C:\\eggs') Permanently Deleting Files and Folders Calling os.unlink(path) or Path.unlink() will delete the file at path. Calling os.rmdir(path) or Path.rmdir() will delete the folder at path. This folder must be empty of any files or folders. Calling shutil.rmtree(path) will remove the folder at path, and all files and folders it contains will also be deleted. Safe Deletes with the send2trash Module You can install this module by running pip install send2trash from a Terminal window. import send2trash with open('bacon.txt', 'a') as bacon_file: # creates the file bacon_file.write('Bacon is not a vegetable.') send2trash.send2trash('bacon.txt') Walking a Directory Tree import os for folder_name, subfolders, filenames in os.walk('C:\\delicious'): print('The current folder is {}'.format(folder_name)) for subfolder in subfolders: print('SUBFOLDER OF {}: {}'.format(folder_name, subfolder)) for filename in filenames: print('FILE INSIDE {}: {}'.format(folder_name, filename)) print('') pathlib provides a lot more functionality than the ones listed above, like getting file name, getting file extension, reading/writing a file without manually opening it, etc. Check out the official documentation if you want to know more! Reading and Writing Files The File Reading/Writing Process To read/write to a file in Python, you will want to use the with statement, which will close the file for you after you are done. Opening and reading files with the open function with open('C:\\Users\\your_home_folder\\hello.txt') as hello_file: hello_content = hello_file.read() hello_content Alternatively, you can use the readlines() method to get a list of string values from the file, one string for each line of text: with open('sonnet29.txt') as sonnet_file: sonnet_file.readlines() You can also iterate through the file line by line: with open('sonnet29.txt') as sonnet_file: for line in sonnet_file: # note the new line character will be included in the line print(line, end='') Writing to Files with open('bacon.txt', 'w') as bacon_file: bacon_file.write('Hello world!\n') with open('bacon.txt', 'a') as bacon_file: bacon_file.write('Bacon is not a vegetable.') with open('bacon.txt') as bacon_file: content = bacon_file.read() print(content) Saving Variables with the shelve Module To save variables: import shelve cats = ['Zophie', 'Pooka', 'Simon'] with shelve.open('mydata') as shelf_file: shelf_file['cats'] = cats To open and read variables: with shelve.open('mydata') as shelf_file: print(type(shelf_file)) print(shelf_file['cats']) Just like dictionaries, shelf values have keys() and values() methods that will return list-like values of the keys and values in the shelf. Since these methods return list-like values instead of true lists, you should pass them to the list() function to get them in list form. with shelve.open('mydata') as shelf_file: print(list(shelf_file.keys())) print(list(shelf_file.values())) Saving Variables with pprint.pformat import pprint cats = [{'name': 'Zophie', 'desc': 'chubby'}, {'name': 'Pooka', 'desc': 'fluffy'}] pprint.pformat(cats) with open('myCats.py', 'w') as file_obj: file_obj.write('cats = {}\n'.format(pprint.pformat(cats))) Reading ZIP Files import zipfile, os os.chdir('C:\\') # move to the folder with example.zip with zipfile.ZipFile('example.zip') as example_zip: print(example_zip.namelist()) spam_info = example_zip.getinfo('spam.txt') print(spam_info.file_size) print(spam_info.compress_size) print('Compressed file is %sx smaller!' % (round(spam_info.file_size / spam_info.compress_size, 2))) Extracting from ZIP Files The extractall() method for ZipFile objects extracts all the files and folders from a ZIP file into the current working directory. import zipfile, os os.chdir('C:\\') # move to the folder with example.zip with zipfile.ZipFile('example.zip') as example_zip: example_zip.extractall() The extract() method for ZipFile objects will extract a single file from the ZIP file. Continue the interactive shell example: with zipfile.ZipFile('example.zip') as example_zip: print(example_zip.extract('spam.txt')) print(example_zip.extract('spam.txt', 'C:\\some\\new\\folders')) Creating and Adding to ZIP Files import zipfile with zipfile.ZipFile('new.zip', 'w') as new_zip: new_zip.write('spam.txt', compress_type=zipfile.ZIP_DEFLATED) This code will create a new ZIP file named new.zip that has the compressed contents of spam.txt. JSON, YAML and configuration files JSON Open a JSON file with: import json with open("filename.json", "r") as f: content = json.loads(f.read()) Write a JSON file with: import json content = {"name": "Joe", "age": 20} with open("filename.json", "w") as f: f.write(json.dumps(content, indent=2)) YAML Compared to JSON, YAML allows a much better humain maintainance and gives ability to add comments. It is a convinient choice for configuration files where human will have to edit. There are two main librairies allowing to access to YAML files: PyYaml Ruamel.yaml Install them using pip install in your virtual environment. The first one it easier to use but the second one, Ruamel, implements much better the YAML specification, and allow for example to modify a YAML content without altering comments. Open a YAML file with: from ruamel.yaml import YAML with open("filename.yaml") as f: yaml=YAML() yaml.load(f) Anyconfig Anyconfig is a very handy package allowing to abstract completly the underlying configuration file format. It allows to load a Python dictionary from JSON, YAML, TOML, and so on. Install it with: pip install anyconfig Usage: import anyconfig conf1 = anyconfig.load("/path/to/foo/conf.d/a.yml") Debugging Raising Exceptions Exceptions are raised with a raise statement. In code, a raise statement consists of the following: The raise keyword A call to the Exception() function A string with a helpful error message passed to the Exception() function raise Exception('This is the error message.') Traceback (most recent call last): File "<pyshell#191>", line 1, in <module> raise Exception('This is the error message.') Exception: This is the error message. Often it's the code that calls the function, not the function itself, that knows how to handle an expection. So you will commonly see a raise statement inside a function and the try and except statements in the code calling the function. def box_print(symbol, width, height): if len(symbol) != 1: raise Exception('Symbol must be a single character string.') if width <= 2: raise Exception('Width must be greater than 2.') if height <= 2: raise Exception('Height must be greater than 2.') print(symbol * width) for i in range(height - 2): print(symbol + (' ' * (width - 2)) + symbol) print(symbol * width) for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)): try: box_print(sym, w, h) except Exception as err: print('An exception happened: ' + str(err)) Getting the Traceback as a String The traceback is displayed by Python whenever a raised exception goes unhandled. But can also obtain it as a string by calling traceback.format_exc(). This function is useful if you want the information from an exception's traceback but also want an except statement to gracefully handle the exception. You will need to import Python's traceback module before calling this function. import traceback try: raise Exception('This is the error message.') except: with open('errorInfo.txt', 'w') as error_file: error_file.write(traceback.format_exc()) print('The traceback info was written to errorInfo.txt.') The 116 is the return value from the write() method, since 116 characters were written to the file. The traceback text was written to errorInfo.txt. Traceback (most recent call last): File "<pyshell#28>", line 2, in <module> Exception: This is the error message. Assertions An assertion is a sanity check to make sure your code isn't doing something obviously wrong. These sanity checks are performed by assert statements. If the sanity check fails, then an AssertionError exception is raised. In code, an assert statement consists of the following: The assert keyword A condition (that is, an expression that evaluates to True or False) A comma A string to display when the condition is False pod_bay_door_status = 'open' assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' pod_bay_door_status = 'I\'m sorry, Dave. I\'m afraid I can\'t do that.' assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' In plain English, an assert statement says, “I assert that this condition holds true, and if not, there is a bug somewhere in the program.” Unlike exceptions, your code should not handle assert statements with try and except; if an assert fails, your program should crash. By failing fast like this, you shorten the time between the original cause of the bug and when you first notice the bug. This will reduce the amount of code you will have to check before finding the code that's causing the bug. Disabling Assertions Assertions can be disabled by passing the -O option when running Python. Logging To enable the logging module to display log messages on your screen as your program runs, copy the following to the top of your program (but under the #! python shebang line): import logging logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s') Say you wrote a function to calculate the factorial of a number. In mathematics, factorial 4 is 1 × 2 × 3 × 4, or 24. Factorial 7 is 1 × 2 × 3 × 4 × 5 × 6 × 7, or 5,040. Open a new file editor window and enter the following code. It has a bug in it, but you will also enter several log messages to help yourself figure out what is going wrong. Save the program as factorialLog.py. import logging logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s') logging.debug('Start of program') def factorial(n): logging.debug('Start of factorial(%s)' % (n)) total = 1 for i in range(1, n + 1): total *= i logging.debug('i is ' + str(i) + ', total is ' + str(total)) logging.debug('End of factorial(%s)' % (n)) return total print(factorial(5)) logging.debug('End of program') Logging Levels Logging levels provide a way to categorize your log messages by importance. There are five logging levels, described in Table 10-1 from least to most important. Messages can be logged at each level using a different logging function. Level Logging Function Description DEBUG logging.debug() The lowest level. Used for small details. Usually you care about these messages only when diagnosing problems. INFO logging.info() Used to record information on general events in your program or confirm that things are working at their point in the program. WARNING logging.warning() Used to indicate a potential problem that doesn't prevent the program from working but might do so in the future. ERROR logging.error() Used to record an error that caused the program to fail to do something. CRITICAL logging.critical() The highest level. Used to indicate a fatal error that has caused or is about to cause the program to stop running entirely. Disabling Logging After you've debugged your program, you probably don't want all these log messages cluttering the screen. The logging.disable() function disables these so that you don't have to go into your program and remove all the logging calls by hand. import logging logging.basicConfig(level=logging.INFO, format=' %(asctime)s -%(levelname)s - %(message)s') logging.critical('Critical error! Critical error!') logging.disable(logging.CRITICAL) logging.critical('Critical error! Critical error!') logging.error('Error! Error!') Logging to a File Instead of displaying the log messages to the screen, you can write them to a text file. The logging.basicConfig() function takes a filename keyword argument, like so: import logging logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') Lambda Functions This function: def add(x, y): return x + y add(5, 3) Is equivalent to the lambda function: add = lambda x, y: x + y add(5, 3) It's not even need to bind it to a name like add before:(lambda x, y: x + y)(5, 3) Like regular nested functions, lambdas also work as lexical closures: def make_adder(n): return lambda x: x + n plus_3 = make_adder(3) plus_5(4) Note: lambda can only evaluate an expression, like a single line of code. Ternary Conditional Operator Many programming languages have a ternary operator, which define a conditional expression. The most common usage is to make a terse simple conditional assignment statement. In other words, it offers one-line code to evaluate the first expression if the condition is true, otherwise it evaluates the second expression.<expression1> if <condition> else <expression2> Example: age = 15 print('kid' if age < 18 else 'adult') Ternary operators can be changed: age = 15 print('kid' if age < 13 else 'teenager' if age < 18 else 'adult') The code above is equivalent to: if age < 18: if age < 12: print('kid') else: print('teenager') else: print('adult') args and kwargs The names args and kwargs are arbitrary - the important thing are the * and ** operators. They can mean: In a function declaration, * means “pack all remaining positional arguments into a tuple named <name>”, while ** is the same for keyword arguments (except it uses a dictionary, not a tuple). In a function call, * means “unpack tuple or list named <name> to positional arguments at this position”, while ** is the same for keyword arguments. For example you can make a function that you can use to call any other function, no matter what parameters it has: def forward(f, *args, **kwargs): return f(*args, **kwargs) Inside forward, args is a tuple (of all positional arguments except the first one, because we specified it - the f), kwargs is a dict. Then we call f and unpack them so they become normal arguments to f. You use *args when you have an indefinite amount of positional arguments. def fruits(*args): for fruit in args: print(fruit) fruits("apples", "bananas", "grapes") Similarly, you use **kwargs when you have an indefinite number of keyword arguments. def fruit(**kwargs): for key, value in kwargs.items(): print("{0}: {1}".format(key, value)) fruit(name = "apple", color = "red") def show(arg1, arg2, *args, kwarg1=None, kwarg2=None, **kwargs): print(arg1) print(arg2) print(args) print(kwarg1) print(kwarg2) print(kwargs) data1 = [1,2,3] data2 = [4,5,6] data3 = {'a':7,'b':8,'c':9} show(*data1,*data2, kwarg1="python",kwarg2="cheatsheet",**data3) show(*data1, *data2, **data3) If you do not specify ** for kwargs show(*data1, *data2, *data3) Thinks to Remember(args) Functions can accept a variable number of positional arguments by using *args in the def statement. You can use the items from a sequence as the positional arguments for a function with the * operator. Using the * operator with a generator may cause your program to run out of memory and crash. Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs. Thinks to remember(kwargs) Function arguments can be specified by position or by keyword. Keywords make it clear what the purpose of each argument is when it would be confusing with only positional arguments. Keyword arguments with default values make it easy to add new behaviors to a function, especially when the function has existing callers. Optional keyword arguments should always be passed by keyword instead of by position. Context Manager While Python's context managers are widely used, few understand the purpose behind their use. These statements, commonly used with reading and writing files, assist the application in conserving system memory and improve resource management by ensuring specific resources are only in use for certain processes. with statement A context manager is an object that is notified when a context (a block of code) starts and ends. You commonly use one with the with statement. It takes care of the notifying. For example, file objects are context managers. When a context ends, the file object is closed automatically: with open(filename) as f: file_contents = f.read() # the open_file object has automatically been closed. Anything that ends execution of the block causes the context manager's exit method to be called. This includes exceptions, and can be useful when an error causes you to prematurely exit from an open file or connection. Exiting a script without properly closing files/connections is a bad idea, that may cause data loss or other problems. By using a context manager you can ensure that precautions are always taken to prevent damage or loss in this way. Writing your own contextmanager using generator syntax It is also possible to write a context manager using generator syntax thanks to the contextlib.contextmanager decorator: import contextlib @contextlib.contextmanager def context_manager(num): print('Enter') yield num + 1 print('Exit') with context_manager(2) as cm: # the following instructions are run when the 'yield' point of the context # manager is reached. # 'cm' will have the value that was yielded print('Right in the middle with cm = {}'.format(cm)) __main__ Top-level script environment __main__ is the name of the scope in which top-level code executes. A module's name is set equal to __main__ when read from standard input, a script, or from an interactive prompt. A module can discover whether or not it is running in the main scope by checking its own __name__, which allows a common idiom for conditionally executing code in a module when it is run as a script or with python -m but not when it is imported: if __name__ == "__main__": # execute only if run as a script main() For a package, the same effect can be achieved by including a main.py module, the contents of which will be executed when the module is run with -m. For example we are developing script which is designed to be used as module, we should do:# Python program to execute function directly def add(a, b): return a+b add(10, 20) # we can test it by calling the function save it as calculate.py # Now if we want to use that module by importing we have to comment out our call, # Instead we can write like this in calculate.py if __name__ == "__main__": add(3, 5) import calculate calculate.add(3, 5) Advantages Every Python module has it's __name__ defined and if this is __main__, it implies that the module is being run standalone by the user and we can do corresponding appropriate actions. If you import this script as a module in another script, the name is set to the name of the script/module. Python files can act as either reusable modules, or as standalone programs. if __name__ == “main”: is used to execute some code only if the file was run directly, and not imported. setup.py The setup script is the centre of all activity in building, distributing, and installing modules using the Distutils. The main purpose of the setup script is to describe your module distribution to the Distutils, so that the various commands that operate on your modules do the right thing. The setup.py file is at the heart of a Python project. It describes all of the metadata about your project. There a quite a few fields you can add to a project to give it a rich set of metadata describing the project. However, there are only three required fields: name, version, and packages. The name field must be unique if you wish to publish your package on the Python Package Index (PyPI). The version field keeps track of different releases of the project. The packages field describes where you've put the Python source code within your project. This allows you to easily install Python packages. Often it's enough to write: python setup.py install and module will install itself. Our initial setup.py will also include information about the license and will re-use the README.txt file for the long_description field. This will look like: from distutils.core import setup setup( name='pythonCheatsheet', version='0.1', packages=['pipenv',], license='MIT', long_description=open('README.txt').read(), ) Find more information visit http://docs.python.org/install/index.html. Dataclasses Dataclasses are python classes but are suited for storing data objects. This module provides a decorator and functions for automatically adding generated special methods such as __init__() and __repr__() to user-defined classes. Features They store data and represent a certain data type. Ex: A number. For people familiar with ORMs, a model instance is a data object. It represents a specific kind of entity. It holds attributes that define or represent the entity. They can be compared to other objects of the same type. Ex: A number can be greater than, less than, or equal to another number. Python 3.7 provides a decorator dataclass that is used to convert a class into a dataclass. python 2.7 class Number: def __init__(self, val): self.val = val obj = Number(2) obj.val with dataclass from dataclasses import dataclass @dataclass class Number: val: int obj = Number(2) obj.val Default values It is easy to add default values to the fields of your data class. from dataclasses import dataclass @dataclass class Product: name: str count: int = 0 price: float = 0.0 obj = Product("Python") obj.name obj.count obj.price Type hints It is mandatory to define the data type in dataclass. However, If you don't want specify the datatype then, use typing.Any. from dataclasses import dataclass from typing import Any @dataclass class WithoutExplicitTypes: name: Any value: Any = 42 PART 2: Single line comments start with a number symbol.""" Multiline strings can be written using three "s, and are often used as documentation. """#################################################### 1. Primitive Datatypes and Operators#################################################### You have numbers 3 # => 3 Math is what you would expect 1 + 1 # => 2 8 - 1 # => 7 10 * 2 # => 20 35 / 5 # => 7.0 Integer division rounds down for both positive and negative numbers. 5 // 3 # => 1 -5 // 3 # => -2 5.0 // 3.0 # => 1.0 # works on floats too -5.0 // 3.0 # => -2.0 The result of division is always a float 10.0 / 3 # => 3.3333333333333335 Modulo operation 7 % 3 # => 1 Exponentiation (x**y, x to the yth power) 2**3 # => 8 Enforce precedence with parentheses(1 + 3) * 2 # => 8 Boolean values are primitives (Note: the capitalization) True False negate with not not True # => False not False # => True Boolean Operators Note "and" and "or" are case-sensitive True and False # => False False or True # => True True and False are actually 1 and 0 but with different keywords True + True # => 2 True * 8 # => 8 False - 5 # => -5 Comparison operators look at the numerical value of True and False 0 == False # => True 1 == True # => True 2 == True # => False -5 != False # => True Using boolean logical operators on ints casts them to booleans for evaluation, but their non-cast value is returned Don't mix up with bool(ints) and bitwise and/or (&,|) bool(0) # => False bool(4) # => True bool(-6) # => True 0 and 2 # => 0 -5 or 0 # => -5 Equality is == 1 == 1 # => True 2 == 1 # => False Inequality is != 1 != 1 # => False 2 != 1 # => True More comparisons 1 < 10 # => True 1 > 10 # => False 2 <= 2 # => True 2 >= 2 # => True Seeing whether a value is in a range 1 < 2 and 2 < 3 # => True 2 < 3 and 3 < 2 # => False Chaining makes this look nicer 1 < 2 < 3 # => True 2 < 3 < 2 # => False(is vs. ==) is checks if two variables refer to the same object, but == checks if the objects pointed to have the same values. a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4] b = a # Point b at what a is pointing to b is a # => True, a and b refer to the same object b == a # => True, a's and b's objects are equal b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4] b is a # => False, a and b do not refer to the same object b == a # => True, a's and b's objects are equal Strings are created with " or '"This is a string." 'This is also a string.' Strings can be added too! But try not to do this."Hello " + "world!" # => "Hello world!" String literals (but not variables) can be concatenated without using '+'"Hello " "world!" # => "Hello world!" A string can be treated like a list of characters"This is a string"[0] # => 'T' You can find the length of a string len("This is a string") # => 16.format can be used to format strings, like this:"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated" You can repeat the formatting arguments to save some typing."{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")=> "Jack be nimble, Jack be quick, Jack jump over the candle stick" You can use keywords if you don't want to count."{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna" If your Python 3 code also needs to run on Python 2.5 and below, you can also still use the old style of formatting:"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way" You can also format using f-strings or formatted string literals (in Python 3.6+) name = "Reiko" f"She said her name is {name}." # => "She said her name is Reiko" You can basically put any Python statement inside the braces and it will be output in the string. f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long." None is an object None # => None Don't use the equality "==" symbol to compare objects to None Use "is" instead. This checks for equality of object identity."etc" is None # => False None is None # => True None, 0, and empty strings/lists/dicts/tuples all evaluate to False. All other values are True bool(0) # => False bool("") # => False bool([]) # => False bool({}) # => False bool(()) # => False#################################################### 2. Variables and Collections#################################################### Python has a print function print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you! By default the print function also prints out a newline at the end. Use the optional argument end to change the end string. print("Hello, World", end="!") # => Hello, World! Simple way to get input data from console input string var = input("Enter some data: ") # Returns the data as a string Note: In earlier versions of Python, input() method was named as raw_input() There are no declarations, only assignments. Convention is to use lower case with_underscores some var = 5 some var # => 5 Accessing a previously unassigned variable is an exception. See Control Flow to learn more about exception handling. some unknown var # Raises a NameError if can be used as an expression Equivalent of C's '?:' ternary operator"yahoo!" if 3 > 2 else 2 # => "yahoo!" Lists store sequences li = [] You can start with a prefilled list other_li = [4, 5, 6] Add stuff to the end of a list with append li.append(1) # li is now [1] li.append(2) # li is now [1, 2] li.append(4) # li is now [1, 2, 4] li.append(3) # li is now [1, 2, 4, 3] Remove from the end with pop li.pop() # => 3 and li is now [1, 2, 4] Let's put it back li.append(3) # li is now [1, 2, 4, 3] again. Access a list like you would any array li[0] # => 1 Look at the last element li[-1] # => 3 Looking out of bounds is an IndexError li[4] # Raises an IndexError You can look at ranges with slice syntax. The start index is included, the end index is not(It's a closed/open range for you mathy types.) li[1:3] # Return list from index 1 to 3 => [2, 4] li[2:] # Return list starting from index 2 => [4, 3] li[:3] # Return list from beginning until index 3 => [1, 2, 4] li[::2] # Return list selecting every second entry => [1, 4] li[::-1] # Return list in reverse order => [3, 4, 2, 1] Use any combination of these to make advanced slices li[start:end:step] Make a one layer deep copy using slices li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false. Remove arbitrary elements from a list with "del" del li[2] # li is now [1, 2, 3] Remove first occurrence of a value li.remove(2) # li is now [1, 3] li.remove(2) # Raises a ValueError as 2 is not in the list Insert an element at a specific index li.insert(1, 2) # li is now [1, 2, 3] again Get the index of the first item found matching the argument li.index(2) # => 1 li.index(4) # Raises a ValueError as 4 is not in the list You can add lists Note: values for li and for other_li are not modified. li + other_li # => [1, 2, 3, 4, 5, 6] Concatenate lists with "extend()" li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6] Check for existence in a list with "in" 1 in li # => True Examine the length with "len()" len(li) # => 6 Tuples are like lists but are immutable. tup = (1, 2, 3) tup[0] # => 1 tup[0] = 3 # Raises a TypeError Note that a tuple of length one has to have a comma after the last element but tuples of other lengths, even zero, do not. type((1)) # => <class 'int'> type((1,)) # => <class 'tuple'> type(()) # => <class 'tuple'> You can do most of the list operations on tuples too len(tup) # => 3 tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) tup[:2] # => (1, 2) 2 in tup # => True You can unpack tuples (or lists) into variables a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3 You can also do extended unpacking a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4 Tuples are created by default if you leave out the parentheses d, e, f = 4, 5, 6 # tuple 4, 5, 6 is unpacked into variables d, e and f respectively such that d = 4, e = 5 and f = 6 Now look how easy it is to swap two values e, d = d, e # d is now 5 and e is now 4 Dictionaries store mappings from keys to values empty_dict = {} Here is a prefilled dictionary filled_dict = {"one": 1, "two": 2, "three": 3} Note keys for dictionaries have to be immutable types. This is to ensure that the key can be converted to a constant hash value for quick look-ups. Immutable types include ints, floats, strings, tuples. invalid dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list' valid dict = {(1,2,3):[1,2,3]} # Values can be of any type, however. Look up values with [] filled_dict["one"] # => 1 Get all keys as an iterable with "keys()". We need to wrap the call in list() to turn it into a list. We'll talk about those later. Note - for Python versions <3.7, dictionary key ordering is not guaranteed. Your results might not match the example below exactly. However, as of Python 3.7, dictionary items maintain the order at which they are inserted into the dictionary. list(filled dict.keys()) # => ["three", "two", "one"] in Python <3.7 list(filled dict.keys()) # => ["one", "two", "three"] in Python 3.7+ Get all values as an iterable with "values()". Once again we need to wrap it in list() to get it out of the iterable. Note - Same as above regarding key ordering. list(filled dict.values()) # => [3, 2, 1] in Python <3.7 list(filled dict.values()) # => [1, 2, 3] in Python 3.7+ Check for existence of keys in a dictionary with "in""one" in filled dict # => True 1 in filled dict # => False Looking up a non-existing key is a KeyError filled_dict["four"] # KeyError Use "get()" method to avoid the KeyError filled dict.get("one") # => 1 filled dict.get("four") # => None The get method supports a default argument when the value is missing filled dict.get("one", 4) # => 1 filled dict.get("four", 4) # => 4"setdefault()" inserts into a dictionary only if the given key isn't present filled dict.setdefault("five", 5) # filled dict["five"] is set to 5 filled dict.setdefault("five", 6) # filled dict["five"] is still 5 Adding to a dictionary filled dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4} filled dict["four"] = 4 # another way to add to dict Remove keys from a dictionary with del del filled_dict["one"] # Removes the key "one" from filled dict From Python 3.5 you can also use the additional unpacking options{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2} {'a': 1, **{'a': 2}} # => {'a': 2} Sets store ... well sets empty_set = set() Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry. some set = {1, 1, 2, 2, 3, 4} # some set is now {1, 2, 3, 4} Similar to keys of a dictionary, elements of a set have to be immutable. invalid set = {[1], 1} # => Raises a TypeError: unhashable type: 'list' valid set = {(1,), 1} Add one more item to the set filled set = some set filled set.add(5) # filled set is now {1, 2, 3, 4, 5} Sets do not have duplicate elements filled_set.add(5) # it remains as before {1, 2, 3, 4, 5} Do set intersection with & other set = {3, 4, 5, 6} filled set & other_set # => {3, 4, 5} Do set union with | filled set | other set # => {1, 2, 3, 4, 5, 6} Do set difference with -{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} Do set symmetric difference with ^{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} Check if set on the left is a superset of set on the right{1, 2} >= {1, 2, 3} # => False Check if set on the left is a subset of set on the right{1, 2} <= {1, 2, 3} # => True Check for existence in a set with in 2 in filled set # => True 10 in filled set # => False#################################################### 3. Control Flow and Iterables#################################################### Let's just make a variable some_var = 5 Here is an if statement. Indentation is significant in Python! Convention is to use four spaces, not tabs. This prints "some_var is smaller than 10" if some var > 10: print("some var is totally bigger than 10.") elif some var < 10: # This elif clause is optional. print("some var is smaller than 10.") else: # This is optional too. print("some_var is indeed 10.")""" For loops iterate over lists prints: dog is a mammal cat is a mammal mouse is a mammal """ for animal in ["dog", "cat", "mouse"]: # You can use format() to interpolate formatted strings print("{} is a mammal".format(animal))""" "range(number)" returns an iterable of numbers from zero to the given number prints: 0 1 2 3 """ for i in range(4): print(i)""" "range(lower, upper)" returns an iterable of numbers from the lower number to the upper number prints: 4 5 6 7 """ for i in range(4, 8): print(i)""" "range(lower, upper, step)" returns an iterable of numbers from the lower number to the upper number, while incrementing by step. If step is not indicated, the default value is 1. prints: 4 6 """ for i in range(4, 8, 2): print(i)""" To loop over a list, and retrieve both the index and the value of each item in the list prints: 0 dog 1 cat 2 mouse """ list = ["dog", "cat", "mouse"] for i, value in enumerate(list): print(i, value)""" While loops go until a condition is no longer met. prints: 0 1 2 3 """ x = 0 while x < 4: print(x) x += 1 # Shorthand for x = x + 1 Handle exceptions with a try/except block try: # Use "raise" to raise an error raise IndexError("This is an index error") except IndexError as e: pass # Pass is just a no-op. Usually you would do recovery here. except (TypeError, NameError): pass # Multiple exceptions can be handled together, if required. else: # Optional clause to the try/except block. Must follow all except blocks print("All good!") # Runs only if the code in try raises no exceptions finally: # Execute under all circumstances print("We can clean up resources here") Instead of try/finally to cleanup resources you can use a with statement with open("myfile.txt") as f: for line in f: print(line) Writing to a file contents = {"aa": 12, "bb": 21} with open("myfile1.txt", "w+") as file: file.write(str(contents)) # writes a string to a file with open("myfile2.txt", "w+") as file: file.write(json.dumps(contents)) # writes an object to a file Reading from a file with open('myfile1.txt', "r+") as file: contents = file.read() # reads a string from a file print(contents) print: {"aa": 12, "bb": 21} with open('myfile2.txt', "r+") as file: contents = json.load(file) # reads a json object from a file print(contents) print: {"aa": 12, "bb": 21} Python offers a fundamental abstraction called the Iterable. An iterable is an object that can be treated as a sequence. The object returned by the range function, is an iterable. filled dict = {"one": 1, "two": 2, "three": 3} our iterable = filled dict.keys() print(our iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface. We can loop over it. for i in our_iterable: print(i) # Prints one, two, three However we cannot address elements by index. our_iterable[1] # Raises a TypeError An iterable is an object that knows how to create an iterator. our iterator = iter(our iterable) Our iterator is an object that can remember the state as we traverse through it. We get the next object with "next()". next(our_iterator) # => "one" It maintains state as we iterate. next(our iterator) # => "two" next(our iterator) # => "three" After the iterator has returned all of its data, it raises a StopIteration exception next(our_iterator) # Raises StopIteration We can also loop over it, in fact, "for" does this implicitly! our iterator = iter(our iterable) for i in our_iterator: print(i) # Prints one, two, three You can grab all the elements of an iterable or iterator by calling list() on it. list(our iterable) # => Returns ["one", "two", "three"] list(our iterator) # => Returns [] because state is saved#################################################### 4. Functions#################################################### Use "def" to create new functions def add(x, y): print("x is {} and y is {}".format(x, y)) return x + y # Return values with a return statement Calling functions with parameters add(5, 6) # => prints out "x is 5 and y is 6" and returns 11 Another way to call functions is with keyword arguments add(y=6, x=5) # Keyword arguments can arrive in any order. You can define functions that take a variable number of positional arguments def varargs(*args): return args varargs(1, 2, 3) # => (1, 2, 3) You can define functions that take a variable number of keyword arguments, as well def keyword_args(**kwargs): return kwargs Let's call it to see what happens keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} You can do both at once, if you like def all the args(*args, **kwargs): print(args) print(kwargs) """ all the args(1, 2, a=3, b=4) prints: (1, 2) {"a": 3, "b": 4} """ When calling functions, you can do the opposite of args/kwargs! Use * to expand tuples and use ** to expand kwargs. args = (1, 2, 3, 4) kwargs = {"a": 3, "b": 4} all the args( args) # equivalent to all the args(1, 2, 3, 4) all the args(\*kwargs) # equivalent to all the args(a=3, b=4) all the args( args, \*kwargs) # equivalent to all the args(1, 2, 3, 4, a=3, b=4) Returning multiple values (with tuple assignments) def swap(x, y): return y, x # Return multiple values as a tuple without the parenthesis. # (Note: parenthesis have been excluded but can be included) x = 1 y = 2 x, y = swap(x, y) # => x = 2, y = 1(x, y) = swap(x,y) # Again parenthesis have been excluded but can be included. Function Scope x = 5 def set_x(num): # Local var x not the same as global variable x x = num # => 43 print(x) # => 43 def set global x(num): global x print(x) # => 5 x = num # global var x is now set to 6 print(x) # => 6 set x(43) set global_x(6) Python has first class functions def create_adder(x): def adder(y): return x + y return adder add 10 = create adder(10) add_10(3) # => 13 There are also anonymous functions(lambda x: x > 2)(3) # => True (lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 There are built-in higher order functions list(map(add_10, [1, 2, 3])) # => [11, 12, 13] list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3] list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7] We can use list comprehensions for nice maps and filters List comprehension stores the output as a list which can itself be a nested list[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] [x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] You can construct set and dict comprehensions as well.{x for x in 'abcddeef' if x not in 'abc'} # => {'d', 'e', 'f'} {x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}#################################################### 5. Modules#################################################### You can import modules import math print(math.sqrt(16)) # => 4.0 You can get specific functions from a module from math import ceil, floor print(ceil(3.7)) # => 4.0 print(floor(3.7)) # => 3.0 You can import all functions from a module. Warning: this is not recommended from math import * You can shorten module names import math as m math.sqrt(16) == m.sqrt(16) # => True Python modules are just ordinary Python files. You can write your own, and import them. The name of the module is the same as the name of the file. You can find out which functions and attributes are defined in a module. import math dir(math) If you have a Python script named math.py in the same folder as your current script, the file math.py will be loaded instead of the built-in Python module. This happens because the local folder has priority over Python's built-in libraries.#################################################### 6. Classes#################################################### We use the "class" statement to create a class class Human:# A class attribute. It is shared by all instances of this class species = "H. sapiens" # Basic initializer, this is called when this class is instantiated. # Note that the double leading and trailing underscores denote objects # or attributes that are used by Python but that live in user-controlled # namespaces. Methods(or objects or attributes) like: __init__, __str__, # __repr__ etc. are called special methods (or sometimes called dunder methods) # You should not invent such names on your own. def __init__(self, name): # Assign the argument to the instance's name attribute self.name = name # Initialize property self._age = 0 # An instance method. All methods take "self" as the first argument def say(self, msg): print("{name}: {message}".format(name=self.name, message=msg)) # Another instance method def sing(self): return 'yo... yo... microphone check... one two... one two...' # A class method is shared among all instances # They are called with the calling class as the first argument @classmethod def get_species(cls): return cls.species # A static method is called without a class or instance reference @staticmethod def grunt(): return "*grunt*" # A property is just like a getter. # It turns the method age() into an read-only attribute of the same name. # There's no need to write trivial getters and setters in Python, though. @property def age(self): return self._age # This allows the property to be set @age.setter def age(self, age): self._age = age # This allows the property to be deleted @age.deleter def age(self): del self._age When a Python interpreter reads a source file it executes all its code. This name check makes sure this code block is only executed when this module is the main program. if name == ' main': # Instantiate a class i = Human(name="Ian") i.say("hi") # "Ian: hi" j = Human("Joel") j.say("hello") # "Joel: hello" # i and j are instances of type Human, or in other words: they are Human objects# Call our class method i.say(i.get_species()) # "Ian: H. sapiens" # Change the shared attribute Human.species = "H. neanderthalensis" i.say(i.get_species()) # => "Ian: H. neanderthalensis" j.say(j.get_species()) # => "Joel: H. neanderthalensis" # Call the static method print(Human.grunt()) # => "*grunt*" # Cannot call static method with instance of object # because i.grunt() will automatically put "self" (the object i) as an argument print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given # Update the property for this instance i.age = 42 # Get the property i.say(i.age) # => "Ian: 42" j.say(j.age) # => "Joel: 0" # Delete the property del i.age # i.age # => this would raise an AttributeError #################################################### 6.1 Inheritance#################################################### Inheritance allows new child classes to be defined that inherit methods and variables from their parent class. Using the Human class defined above as the base or parent class, we can define a child class, Superhero, which inherits the class variables like"species", "name", and "age", as well as methods, like "sing" and "grunt" from the Human class, but can also have its own unique properties. To take advantage of modularization by file you could place the classes above in their own files, say, human.py To import functions from other files use the following format from "filename-without-extension" import "function-or-class" from human import Human Specify the parent class(es) as parameters to the class definition class Superhero(Human):# If the child class should inherit all of the parent's definitions without # any modifications, you can just use the "pass" keyword (and nothing else) # but in this case it is commented out to allow for a unique child class: # pass # Child classes can override their parents' attributes species = 'Superhuman' # Children automatically inherit their parent class's constructor including # its arguments, but can also define additional arguments or definitions # and override its methods such as the class constructor. # This constructor inherits the "name" argument from the "Human" class and # adds the "superpower" and "movie" arguments: def __init__(self, name, movie=False, superpowers=["super strength", "bulletproofing"]): # add additional class attributes: self.fictional = True self.movie = movie # be aware of mutable default values, since defaults are shared self.superpowers = superpowers # The "super" function lets you access the parent class's methods # that are overridden by the child, in this case, the __init__ method. # This calls the parent class constructor: super().__init__(name) # override the sing method def sing(self): return 'Dun, dun, DUN!' # add an additional instance method def boast(self): for power in self.superpowers: print("I wield the power of {pow}!".format(pow=power)) if name == ' main': sup = Superhero(name="Tick")# Instance type checks if isinstance(sup, Human): print('I am human') if type(sup) is Superhero: print('I am a superhero') # Get the Method Resolution search Order used by both getattr() and super() # This attribute is dynamic and can be updated print(Superhero.__mro__) # => (<class '__main__.Superhero'>, # => <class 'human.Human'>, <class 'object'>) # Calls parent method but uses its own class attribute print(sup.get_species()) # => Superhuman # Calls overridden method print(sup.sing()) # => Dun, dun, DUN! # Calls method from Human sup.say('Spoon') # => Tick: Spoon # Call method that exists only in Superhero sup.boast() # => I wield the power of super strength! # => I wield the power of bulletproofing! # Inherited class attribute sup.age = 31 print(sup.age) # => 31 # Attribute that only exists within Superhero print('Am I Oscar eligible? ' + str(sup.movie)) #################################################### 6.2 Multiple Inheritance#################################################### Another class definition bat.py class Bat: species = 'Baty' def __init__(self, can_fly=True): self.fly = can_fly # This class also has a say method def say(self, msg): msg = '... ... ...' return msg # And its own method as well def sonar(self): return '))) ... (((' if name == ' main': b = Bat() print(b.say('hello')) print(b.fly) And yet another class definition that inherits from Superhero and Bat superhero.py from superhero import Superhero from bat import Bat Define Batman as a child that inherits from both Superhero and Bat class Batman(Superhero, Bat): def __init__(self, *args, **kwargs): # Typically to inherit attributes you have to call super: # super(Batman, self).__init__(*args, **kwargs) # However we are dealing with multiple inheritance here, and super() # only works with the next base class in the MRO list. # So instead we explicitly call __init__ for all ancestors. # The use of *args and **kwargs allows for a clean way to pass arguments, # with each parent "peeling a layer of the onion". Superhero.__init__(self, 'anonymous', movie=True, superpowers=['Wealthy'], *args, **kwargs) Bat.__init__(self, *args, can_fly=False, **kwargs) # override the value for the name attribute self.name = 'Sad Affleck' def sing(self): return 'nan nan nan nan nan batman!' if name == ' main': sup = Batman()# Get the Method Resolution search Order used by both getattr() and super(). # This attribute is dynamic and can be updated print(Batman.__mro__) # => (<class '__main__.Batman'>, # => <class 'superhero.Superhero'>, # => <class 'human.Human'>, # => <class 'bat.Bat'>, <class 'object'>) # Calls parent method but uses its own class attribute print(sup.get_species()) # => Superhuman # Calls overridden method print(sup.sing()) # => nan nan nan nan nan batman! # Calls method from Human, because inheritance order matters sup.say('I agree') # => Sad Affleck: I agree # Call method that exists only in 2nd ancestor print(sup.sonar()) # => ))) ... ((( # Inherited class attribute sup.age = 100 print(sup.age) # => 100 # Inherited attribute from 2nd ancestor whose default value was overridden. print('Can I fly? ' + str(sup.fly)) # => Can I fly? False #################################################### 7. Advanced#################################################### Generators help you make lazy code. def double_numbers(iterable): for i in iterable: yield i + i Generators are memory-efficient because they only load the data needed to process the next value in the iterable. This allows them to perform operations on otherwise prohibitively large value ranges. NOTE: range replaces xrange in Python 3. for i in double_numbers(range(1, 900000000)): # range is a generator. print(i) if i >= 30: break Just as you can create a list comprehension, you can create generator comprehensions as well. values = (-x for x in [1,2,3,4,5]) for x in values: print(x) # prints -1 -2 -3 -4 -5 to console/terminal You can also cast a generator comprehension directly to a list. values = (-x for x in [1,2,3,4,5]) gen to list = list(values) print(gen to list) # => [-1, -2, -3, -4, -5] Decorators In this example beg wraps say. If say_please is True then it will change the returned message. from functools import wraps def beg(target function): @wraps(target function) def wrapper( args, \*kwargs): msg, say please = target function( args, \*kwargs) if say_please: return "{} {}".format(msg, "Please! I am poor :(") return msg return wrapper @beg def say(say please=False): msg = "Can you buy me a beer?" return msg, say please print(say()) # Can you buy me a beer? print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
    https://bgoonz-blog.netlify.app/images/py-code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Python at length Understanding variables Variables are simply declarations that are used to store certain values. For instance, the variable name can hold the value of John Smith. Several rules need to be considered when declaring variable names. For starters, a variable name cannot begin with a number. 2name = incorrect #incorrect name = correct #correct Variable names are case sensitive. This means that the variable school is not the same as School. Variables can hold different data types. This includes strings, integers, Booleans, long, lists, and arrays. In Python, we do not need to declare the data type while writing a variable. This is because the code is compiled and interpreted later. The compiler will throw an error in case there is a mismatch in the data types. Let's talk about the different data types. Strings Strings are usually presented in a text format. We will declare a string variable, as shown below. name = “john”school = “Alliance Francaise” When we run print(name), the output will be john. Integers These variables hold numeric values, as shown below. math = 90chemistry = 100biology = 70 We can find the total of the variables above using the following statement. print(math+chemistry+biology) The total is 260. A TypeError is thrown when you try to add a string to an integer, as shwon below. var1 = "30" #stringvar2 = 20 #integer​print(var1+var2)#type error We can sum var1 and var2 by converting var1 to an integer using the int() function. The following code will execute successfully. var1 = "30" #stringvar2 = 20 #integer​print(int(var1)+var2) # Output: 50 Make sure that the variable stores a value that can be converted to an integer before using the int() method. Booleans There are only two Boolean values: True and False. In other words, something can either be true or false. We declare these values, as shown below. Please note that Python is case sensitive. isOn = TrueisChecked = False A bool() method can help convert a value to a boolean. The code snippets below showcase how a bool() function can be used. print(bool("abc")) #returns Trueprint(bool(0)) #returns False The bool() function returns False when there are no parameters. Float This data type consists of numbers that have a decimal place. A perfect example of a float variable is highlighted below. Bmi = 45.7 Understanding lists Lists allow us to store numerous elements in a particular variable. For instance, we can have a list that stores all the student names in a class. We use [] to define a list. students = [] #list example Elements in a list are usually separated by a comma, as shown below. students = [“john”, “Mary Thomas”, “John Smith”] Each element in the above students list has an index. By default, the first index is 0. So the item at index [0] is john, while the value at index 1 is Mary Thomas. A list of integers will look as follows. student_marks = [90, 78, 90, 78] We can access different list functionalities using built-in functions. For instance, to add a value to the student_marks list, we use the append function. student_marks.append("Guardian Angel")print(student_marks) The above function adds Guardian Angel at the end of the student_marks list. When we print the list it shows:#output[90, 78, 90, 78, 'Guardian Angel'] We use len(student_marks) to determine the length of the list. We use the remove() function to delete something from the list. For instance, we can remove 90 from the student_mark list as shown below. student_marks.remove(90)print(student_marks) In lists, negative indices allow us to count elements starting from the last one. For instance, the element with an index of -1 in the above student_marks list is "Guardian Angel". The second last element 78 has an index of -2. Understanding functions or methods Methods are quite critical in programming. They help store reusable code. This means that a person can call already declared methods rather than writing statements from scratch repeatedly. This saves significant time, that can be invested in other productive activities. In Python, we use the def keyword to declare a function. An example of a python method is shown below. def readData(): print('success') The above function prints success when it's invoked. We can also pass data to a method, perform some calculations, and return the results. This is demonstrated in the code snippet below. def calculateTotal(chem, bio): return chem+bio​print(calculateTotal(90,80)) The calculateTotal method takes in two parameters (chem, bio). The function then returns the sum of the two values. It is important to take note of the data types when passing parameters. For instance, the calculateTotal method will not work when we pass in a string as a parameter. This is because the program cannot sum up an integer and a string. As shown above, we can call the calculateTotal method directly from our print statement. print(calculateTotal(90,80)) The return keyword ensures that the method returns a result after execution. Note that a function can also call another method. This is illustrated below. def readData(chem, bio): return chem+bio​def getTotal(): print(readData(90,80)) #calls the readData method​getTotal() Understanding loops Loops are critical because they allow us to iterate through lists, check for different conditions, and continuously execute various statements. The main loops are for and while. For loops As noted, we can use a for loop to iterate through a list, as shown below: student_list = [“John Doore”,”Matu Smith”]for x in student_list: print(x) The for loop above will print every item in the student_list. While loops A while loop can help us check for a particular condition. For instance, while something is true specific statements can be executed. Here is an example of a while loop in action. isChecked = falsewhile isChecked == true: print('Hallo there') Note that the while loop above will be executed indefinitely until isChecked is set to false. You can press ctrl+c to stop the loop. Classes Classes are a vital component of object-oriented programming. When creating a class, you must use the class keyword. Other elements are then nested in the class. Here is an example of a Python class. class Farmer: # a class with the name farmer name = "John" # A variable produce = "1000kgs" # A variable​farmer = Farmer() #instatiating the class as an object. print(farmer.name) # accessing the properties of the Farmer class. Classes can help as group things with similar characteristics. We can also assign values to class variables using the init function. class Farmer: def __init__(self, farmername, produce): self.farmername = farmername self.produce = produce​farmer = Farmer("Carry Sminson", "10,000kgs")​print(farmer.farmername, farmer.produce) In the above Farmer class, the self keyword represents an instance of an object. In other words, it allows us to access the different methods and attributes defined in the class. You can also declare a method in a class and use it later, as shown below. class Farmer: def __init__(self, farmername, produce): self.farmername = farmername self.produce = produce​ def printDetails(self): # Method print(self.farmername, self.produce)​farmer = Farmer("Carry Sminson", "10,000kgs")​farmer.printDetails() Python syntax was made for readability, and easy editing. For example, the python language uses a : and indented code, while javascript and others generally use {} and indented code. Lets create a python 3 repl, and call it Hello World. Now you have a blank file called main.py. Now let us write our first line of code: helloworld.py print('Hello world!') Brian Kernighan actually wrote the first “Hello, World!” program as part of the documentation for the BCPL programming language developed by Martin Richards. Now, press the run button, which obviously runs the code. If you are not using replit, this will not work. You should research how to run a file with your text editor. If you look to your left at the console where hello world was just printed, you can see a >, >>>, or $ depending on what you are using. After the prompt, try typing a line of code. Python 3.6.1 (default, Jun 21 2017, 18:48:35)[GCC 4.9.2] on linuxType "help", "copyright", "credits" or "license" for more information.> print('Testing command line')Testing command line> print('Are you sure this works?')Are you sure this works?> The command line allows you to execute single lines of code at a time. It is often used when trying out a new function or method in the language. Another cool thing that you can generally do with all languages, are comments. In python, a comment starts with a #. The computer ignores all text starting after the #. shortcom.py# Write some comments! If you have a huge comment, do not comment all the 350 lines, just put ''' before it, and ''' at the end. Technically, this is not a comment but a string, but the computer still ignores it, so we will use it. longcom.py'''Dear PYer,I am confused about how you said you could use triple quotes to makeSUPERLONGCOMMENTS!​I am wondering if this is true,and if so,I am wondering if this is correct.​Could you help me with this?​Thanks,Random guy who used your tutorial.'''print('Testing') Unlike many other languages, there is no var, let, or const to declare a variable in python. You simply go name = 'value'. vars1.py x = 5y = 7z = x*y # 35print(z) # => 35 Remember, there is a difference between integers and strings. Remember: String = "". To convert between these two, you can put an int in a str() function, and a string in a int() function. There is also a less used one, called a float. Mainly, these are integers with decimals. Change them using the float() command. vars2.py x = 5x = str(x)b = '5'b = int(b)print('x = ', x, '; b = ', str(b), ';') # => x = 5; b = 5; Instead of using the , in the print function, you can put a + to combine the variables and string. There are many operators in python:+-/* These operators are the same in most languages, and allow for addition, subtraction, division, and multiplicaiton. Now, we can look at a few more complicated ones:%//**+=-=/=*= Research these if you want to find out more… simpleops.py x = 4a = x + 1a = x - 1a = x * 2a = x / 2 You should already know everything shown above, as it is similar to other languages. If you continue down, you will see more complicated ones. complexop.py a += 1a -= 1a *= 2a /= 2 The ones above are to edit the current value of the variable. Sorry to JS users, as there is no i++; or anything. Fun Fact: The python language was named after Monty Python. If you really want to know about the others, view Py Operators​ Like the title? Anyways, a ' and a " both indicate a string, but do not combine them! quotes.py x = 'hello' # Goodx = "hello" # Goodx = "hello' # ERRORRR!!! slicing.py String Slicing You can look at only certain parts of the string by slicing it, using [num:num]. The first number stands for how far in you go from the front, and the second stands for how far in you go from the back. x = 'Hello everybody!'x[1] # 'e'x[-1] # '!'x[5] # ' 'x[1:] # 'ello everybody!'x[:-1] # 'Hello everybod'x[2:-3] # 'llo everyb' Methods and Functions Here is a list of functions/methods we will go over:.strip() len().lower().upper().replace().split() I will make you try these out yourself. See if you can figure out how they work. strings.py x = " Testing, testing, testing, testing "print(x.strip())print(len(x))print(x.lower())print(x.upper())print(x.replace('test', 'runn'))print(x.split(',')) Good luck, see you when you come back! Input is a function that gathers input entered from the user in the command line. It takes one optional parameter, which is the users prompt. inp.py print('Type something: ')x = input()print('Here is what you said: ', x) If you wanted to make it smaller, and look neater to the user, you could do… inp2.py print('Here is what you said: ', input('Type something: ')) Running: inp.py Type something:Hello WorldHere is what you said: Hello World inp2.py Type something: Hello WorldHere is what you said: Hello World Python has created a lot of functions that are located in other .py files. You need to import these modules to gain access to the,, You may wonder why python did this. The purpose of separate modules is to make python faster. Instead of storing millions and millions of functions, , it only needs a few basic ones. To import a module, you must write input <modulename>. Do not add the .py extension to the file name. In this example , we will be using a python created module named random. module.py import random Now, I have access to all functions in the random.py file. To access a specific function in the module, you would do <module>.<function>. For example: module2.py import randomprint(random.randint(3,5)) # Prints a random number between 3 and 5 Pro Tip: Do from random import randint to not have to do random.randint(), just randint() To import all functions from a module, you could do from random import * Loops allow you to repeat code over and over again. This is useful if you want to print Hi with a delay of one second 100 times. for Loop The for loop goes through a list of variables, making a seperate variable equal one of the list every time. Let's say we wanted to create the example above. loop.py from time import sleepfor i in range(100): print('Hello') sleep(.3) This will print Hello with a .3 second delay 100 times. This is just one way to use it, but it is usually used like this: loop2.py import timefor number in range(100): print(number) time.sleep(.1) while Loop The while loop runs the code while something stays true. You would put while <expression>. Every time the loop runs, it evaluates if the expression is True. It it is, it runs the code, if not it continues outside of the loop. For example: while.py while True: # Runs forever print('Hello World!') Or you could do: while2.py import randomposition = '<placeholder>'while position != 1: # will run at least once position = random.randint(1, 10) print(position) The if statement allows you to check if something is True. If so, it runs the code, if not, it continues on. It is kind of like a while loop, but it executes only once. An if statement is written: if.py import randomnum = random.randint(1, 10)if num == 3: print('num is 3. Hooray!!!')if num > 5: print('Num is greater than 5')if num == 12: print('Num is 12, which means that there is a problem with the python language, see if you can figure it out. Extra credit if you can figure it out!') Now, you may think that it would be better if you could make it print only one message. Not as many that are True. You can do that with an elif statement: elif.py import randomnum = random.randint(1, 10)if num == 3: print('Num is three, this is the only msg you will see.')elif num > 2: print('Num is not three, but is greater than 1') Now, you may wonder how to run code if none work. Well, there is a simple statement called else: else.py import randomnum = random.randint(1, 10)if num == 3: print('Num is three, this is the only msg you will see.')elif num > 2: print('Num is not three, but is greater than 1')else: print('No category') So far, you have only seen how to use functions other people have made. Let use the example that you want to print the a random number between 1 and 9, and print different text every time. It is quite tiring to type: Characters: 389 nofunc.py import randomprint(random.randint(1, 9))print('Wow that was interesting.')print(random.randint(1, 9))print('Look at the number above ^')print(random.randint(1, 9))print('All of these have been interesting numbers.')print(random.randint(1, 9))print("these random.randint's are getting annoying to type")print(random.randint(1, 9))print('Hi')print(random.randint(1, 9))print('j') Now with functions, you can seriously lower the amount of characters: Characters: 254 functions.py import randomdef r(t): print(random.randint(1, 9)) print(t)r('Wow that was interesting.')r('Look at the number above ^')r('All of these have been interesting numbers.')r("these random.randint's are getting annoying to type")r('Hi')r('j') Chapter 01 - Getting Ready with Python Installing Python 3, And Launching Python Shell This video should help you get up and running with Python 3​ Installing Python 3 and Launch Python Shell​ Installing Python is really a cakewalk. Search for “Python download” on www.google.com. Download the installable and install it. A quick word of caution on Windows Make sure that you have the check-box “Add Python 3.6 to PATH”, checked. Once you have installed Python, you can launch the Python Shell. Windows - Launch cmd prompt by typing in 'cmd' command. Mac or Linux - Launch up terminal. Command to launch Python 3 is different in Mac. In Mac, type in python3 In other operating systems, including windows, type python You can type code in python shell and code as well! You can use print(5*4), and it shows 20. You can execute the code, and the shell would immediately give you output. Using the the Python Shell is an awesome way to learn Python. Chapter 02 - Introduction To Python Programming Most programmers find programming a lot of fun, and besides, it also gets their work done. Programming mainly involves problem solving, where one makes use of a computer to solve a real world problem. During our journey here, we will approach programming in a very different way. We will not only introduce you to the Python language, but also help you pick up essential problem solving skills. As a programmer, you need to be able to look at a problem, and identify the important programming concepts relevant to solving it. Finally, you need to be able to use the language features and syntax, to express your solution on the computer. While all this looks complex, we want to make it easy for you. Together, we will tackle a variety of programming challenges, using these same steps. We will start with simple challenges (such as a Multiplication Table), and gradually increase the difficulty level over the duration of this book. Learning to program is a lot like learning to ride a bicycle. The first few steps are the most challenging ones. Once you get over these initial steps, your experience will become more and more enjoyable. Are you ready for your first programming challenge? Let's get going now! We wish you all the best. Summary In this step, we: Were introduced to the concept of problem solving Understood how good programmers approach problem solving Step 01: Our First Programming Challenge Our first programming challenge aims to do, what every kid does in math class: read out a multiplication table. We now want to give this task to the computer. Here is the statement of our problem: The Print Multiplication Table Challenge (PMT-Challenge) Compute the multiplication table for 5, with entries from 1 to 10. Display this table. The display needs to be: 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 5 * 8 = 40 5 * 9 = 45 5 * 10 = 50 This is the challenge. For convenience, let's give it a label, say PMT-Challenge. What would be the important concepts we need to learn, to solve this challenge? The following list of concepts would be a good starting point: Statements Expressions Variables Literals Conditionals Loops Methods In the rest of this chapter, we will introduce these concepts to you, one-by-one. We will also show you how learning each concept, takes us closer to a solution to PMT-Challenge. Summary In this step, we: Stated our first programming challenge Identified what programming concepts we need to learn, to solve this challenge Step 02: Breaking Down PMT-Challenge Typically when we do programming, we have problems. Solving the problem typically need a step-by -step approach. Common sense tells us that to solve a complex problem, we break it into smaller parts, and solve each part one by one. Here is how any good programmer worth her salt, would solve a problem: Simplify the problem, by breaking it into sub-problems Solve the sub-problems in stages (in some order), using the language Combine these solutions to get a final solution The PMT-Challenge is no different! Now how do we break it down, and where do we really start? Once again, your common sense will reveal a solution. As a first step, we could get the computer to calculate say, 5 * 3. The second thing we can do, is to try and print the calculated value, in a manner similar to 5 * 3 = 15. Then, we could repeat what we just did, to print out all the entries of the 5 multiplication table. Let's put it down a little more formally: Here is how our draft steps look like Calculate 5 * 3 and print result as 15 Print 5 * 3 = 15 ( 15 is result of previous calculation) Do this ten times, once for each table entry (going from 1 to 10) Let's start with that kind of a game plan, and see where it takes us. Summary In this step, we: Learned that breaking down a problem into sub-problems is a great help Found a way to break down the PMT-Challenge problem Step 03: Introducing Operators And Expressions Let's focus on solving the first sub-problem of PMT-Challenge, the numeric computation. We want the computer to calculate 5 * 5 for example, and print 25 for us. How do we get it to do that? That's what we would be looking at in this step. Snippet-01: Introducing Operators Launch up Python shell. We want to calculate 5 * 5. How do we do that? Using our knowledge of school math, let's try 5 X 5. >>> 5 X 5 File "< stdin >", line 1 5 X 5 ^ SyntaxError: invalid syntax The Python Shell hits back at us, saying “ invalid syntax”. This is how Python complains, when it doesn't fully understand the code you type in. Here, it says our code has a “ SyntaxError”. The reason why it complains, is because ' X' is not a valid operator in Python. The way you can do multiplication is by using the '*' operator .“ 5 into 5” is achieved by the code 5 * 5, and you can see the result 25 being printed. Similarly, 5 * 6 gives us 30. >>> 5 * 6 30 There are a wide range of other operators in Python: 5 + 6 gives a result of 11. 5 - 6 leads to -1.>>> 5 + 611>>> 5 - 6-1 10 / 2, gives an output of 5.0 . There is one interesting operator, **. Let's try 10 ** 3. We ran this code, and the result we get is 1000. Yes you guessed right, the operator performs “to the power of”. “ 10 to the power of 3” is 10 * 10 * 10, or 1000. >>> 10 / 2 5.0 >>> 10 ** 3 1000 Another interesting operator is %, called “ modulo”, which computes the remainder on integer division. If we do 10 % 3, what is the remainder when 10 is divided by 3? 3 * 3 is 9, and 10 - 9 is 1, which is what % returns in this case. Let's look at some terminology: Whatever pieces of code we gave Python shell to run, are called expressions. So, 5 * 5, 5 * 6 and 5 - 6 are all expressions. An expression is composed of operators and operands. In the expression 5 * 6, the two values 5 and 6 are called operands, and the * operator operates on them. The values 5 and 6 are literals, because those are constants which cannot be changed. The cool thing about Python, is that you can even have expressions with multiple operators. Therefore, you can form an expression with 5 + 5 + 5, which evaluates to 15. This is an expression which has three operands, and two + operators. You can even have expressions with different types of operators, such as in 5 + 5 * 5. >>> 5 + 5 + 5 15 >>> 5 + 5 * 5 30 Try and play around with the expressions, and understand the output which results. Summary In this step, we: Learned how to give code input to the Python Shell Understood that Python has a predefined set of operators Used a few types of basic operators and their operands, to form expressions Step 04: Programming Exercise IN-PE-01 At this stage, your smile tells us that you enjoy evaluating Python expressions. What if we tickle your mind a bit, to make sure it hasn't fallen asleep? Here is your first programming exercise. Exercises Write an expression to calculate the number of minutes in a day. Write an expression to calculate the number of seconds in a day. Note You need to solve these problems by yourself. If you are able to work them out, that's fantastic! But if not, that's part of the learning process. Solutions Solution 1 >>> 24 * 60​ 1440 We wanted to calculate the number of minutes in a day. How do we do that? Think about this… How many number of hours are there in a day? 24. And how many minutes does each hour have? It's 60. So if you want to find out the number of minutes in a day, it's 24 * 60, which is 1440. Solution 2 >>> 24 * 60 * 60​ 86400 How many seconds are there in a day? Let's start with the number of hours, 24. The number of minutes in an hour is 60, and The number of seconds in a minute is 60 as well. So it's 24 * 60 * 60, or 86400. Summary In this step, we: Solved a Programming Exercise involving common scenarios, using Python code involving: Expressions Operators Literals Step 05: Puzzles On Expressions Let's look at a few puzzles related to expressions, in this step. Before that, let's revise some of the terminology we had learned earlier. 5 + 6 + 10 is an example of an expression. In this expression, 5, 6 and 10 are operands. The + here is the operator. You can have multiple operators in an expression. We also did mention that the operands, namely 10, 6 and 5, are literals. Their values will not change. Here are a few puzzles coming up, to explore aspects of expressions. Snippet-01: Puzzles On Expressions Think about what would happen when you do something of this kind: 5 $ 2. You're right, it would throw a SyntaxError. When Python does not understand the code you type in, it reports an error. Here, the expression we're typing is 5 $ 2, which does not make sense to Python, hence the SyntaxError. >>> 5 $ 2 File "< stdin >", line 1 5 $ 2 ^ SyntaxError: invalid syntax >>> 5$2 File "< stdin >", line 1 5 $ 2 ^ SyntaxError: invalid syntax Let's say we type in 5+6+10, without any spaces between the operands, and the operators. What do you think will happen? Surprisingly, the Python Shell does calculate the value! >>> 5+6+10 21 In an expression, using spaces makes it easier for you to read it, but it's not mandatory. 5 + 6 + 10 is easier to read than 5+6+10, but does not make any difference to the Python compiler. The next puzzle tries to evaluate 5 / 2, which is “ 5 divided by 2”. What would be the output? 2.5. >>> 5/2 2.5 If you're coming from other programming languages like Java or C, this might be a surprising result. If you try this in Java for instance, you would get 2 as the output. Note that even though both operands are integers, the result of the / operation is a floating point value, 2.5 . Python does what is expected by a programmer! The puzzle after that tries to play with 5 + 5 * 6. What would be the result of this expression? Will it be 5 + 5 or 10, then 10 * 6, which is 60? Or, will it be 5 plus 5 * 6, which is 5 + 30, that's 35? >>> 5 + 5 * 6 35 The correct result is 35. Python decides this is based on the precedence of operators. Operators in Python are divided into two sets as follows:**, *, / and % have higher precedence, or priority.+ and - have a lower precedence. Sub-expressions involving operators from {*, /, %, **} are evaluated before those involving operators from {+, -} Let's try another small puzzle on precedence, with 5 - 2 * 2. What would be the result of this? Will it be 6, or 1? It's 1, because * has a higher precedence than -. Thus 2 * 2 is 4, and 5 - 4 gives us 1. >>> 5 - 2 * 2 1 Let's say we want to execute 5 - 2, to give an output of 2. How do we change the operator precedence? You cannot really change the precedence, but you can add parentheses to group sub-expressions differently. >>> (5 - 2) * 2 6 >>> 5 - ( 2 * 2 ) 1 Parentheses have the highest precedence in Python, and can be used to override operator precedence. (5 - 2) gets calculated first, and the final result of the expression is 6. A positive thing about using parentheses is, that it makes expressions more readable. So even in situations such as 5 - 2 * 2, where we know the result according to precedence, adding parentheses is good. Summary In this step, we went about solving a few puzzles about expressions, touching concepts such as: SyntaxError for incorrect operators White-space in expressions Floating Point division by default Operator Precedence Using parentheses Step 06: Printing Text In the previous step, we learned how to use expressions to compute values. In this step, let's see how we can actually print multiplication table entries, that are readable by the user. Snippet-01: Printing Text How do we go about printing a complete multiplication table entry? We want to print text such as 5 * 6 = 30 . But trying to do so, as we know it, gives us a SyntaxError. Clearly, there is a different way to print text, as compared to an expression. >>> 5 * 6 = 30 File "<stdin>", line 1 SyntaxError: can't assign to operator Let's first try to print a simple piece of text, Hello. Typing in this piece of code directly on Python Shell also gives us an error. >>> Hello Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Hello' is not defined Only expressions work that way, and Hello is not really an expression."Hello" is typically called a string, and represents the text of letters 'H', 'e', 'l', 'l', 'o'. "Hello" is hence different from the number 5. There are a number of in-built functions in Python to help print strings. One of these is the print() function. Can you just say print Hello? >>> print Hello File "<stdin>", line 1 print Hello ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(Hello)? The Python compiler gives you an error, that says “missing parentheses”. Will print(Hello) work? >>> print (Hello) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Hello' is not defined Nope! Again, this one failed because you need to indicate that "Hello" is a string. How do I indicate that "Hello" is a string? By putting it within double quotes. Let's try print ("Hello") >>> print ("Hello") Hello >>> print("Hello") Hello print("Hello") finally results in "Hello" being printed out. To be able to print "Hello", the things we need to do are: Typing the method name print , open parentheses ( , Followed by a double quote " , The text Hello, and another double quote " , finished off with a closed parentheses ). What we have written here is called a statement, a simple piece of code to execute. As part of this statement, we are calling a function, named print(). What exactly are we trying to print? The text "Hello", which is called a parameter or argument, to print(). Now let's get back to what we wanted to do, which is to print 5 * 6 = 30. The most basic version would be something of this kind, print("5 * 6 = 30"). Here, we are passing the entire value in the form of a string. >>> print("5 * 6 = 30") 5 * 6 = 30 This prints the text on the console, as-is. The thing you need to understand here is, we aren't really calculating 30 using the formula 5 * 6, but directly putting text 30 in here. That's called hard-coding. In a later step, we will look at how to actually calculate the value and pass it in. Summary In this step, we: Understood that displaying text on the console is not the same as printing an expression value Learned about the print() function, that is used to print text in Python. Found a way to print the text "5 * 6 = 30" on the console, by hard-coding values in a string Step 07: Puzzles On Utility Methods, And Strings In the previous step, we learned how to print 5 * 6 = 30. It was not a perfect solution, because we hard-coded everything. we used an in-built function named print(), passed a string to it, and invoked the method. In this step, let's look at a number of puzzles related to in-built methods, their parameters, and strings in general. For example, let's do print("5 * 6"), as in the previous step. What does this code result in? >>> print("5*6") 5*6 >>> print('5*6') 5*6 It just prints the string "5 * 6". Let's say we try the code print(5 * 6), >>> print(5*6) 30 Without the double quotes, 5 * 6 is an expression. What will be the output? 30. If you call print() with an expression argument, it prints the value of the expression. However, when we pass something within double quotes, it becomes a piece of text, printed as-is. An interesting thing to note is, that in Python you can use either double-quotes (" and "), or single-quotes (' and ') with text values. Let's look at a few other in-built methods within Python. Consider abs() (which stands for absolute value), a method that accepts a numeric value. You can use abs(10.5), passing 10.5 as a value to it, and it prints the absolute value of 10. >>> abs 10.5 File "<stdin>", line 1 abs 10.5 ^ SyntaxError: invalid syntax >>> abs(10.5) 10.5 If you pass in a string value, will it work? It complains, “ abs() function will not work with a string, it only works with numeric values”. >>> abs("10.5") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: bad operand type for abs(): 'str' Let's say you want to use a function that computes “to the power of”, for instance “ 2 to the power of 5”. In Python, there's an in-built function named pow(), which does just what we need. To pow(), you can pass two parameters and calculate the result. How do you do that? Will this work: pow 2 5? No, not at all. This code does not work as well: pow(2 5). pow(2, 5) is the correct syntax. >>> pow 2 5 File "<stdin>", line 1 pow 2 5 ^ SyntaxError: invalid syntax >>> pow(2 5) File "<stdin>", line 1 pow(2 5) ^ SyntaxError: invalid syntax >>> pow(2, 5) 32 You'll see that 32 is printed. Let's see another example, “ 10 to the power of 3”. pow(10,3) is the alternative to saying 10 ** 3. This gives us 1000, similar to how pow() would. >>> pow(10, 3) 1000 >>> 10 ** 3 1000 max() returns maximum in a set of numbers. min() function returns the minimum value. >>> max(34, 45, 67) 67 >>> min(34, 45, 67) 34 These are some of the in-built functions in Python, and we saw how to call the in-built functions by passing in a varied number of parameters. Python is case sensitive. So let's say I want of calculate pow(2,5). So this would give me 32. Now, what if I say capital 'P' instead of small 'p' here? Pow(2,5) would lead to an error. >>> pow(2,5) 32 >>> Pow(2,5) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Pow' is not defined The only things not case-sensitive in Python, are string values. Earlier we saw that the code print("Hello") displays the text "Hello". Inside a string, the text can be in any case. Hence, print("hello") displays "hello" ,with a small 'h'. >>> print("Hello") Hello >>> print("hello") hello >>> print("hellO") hellO >>> print ( "hellO" ) hellO However inside your code, you need to be very particular about the case of function names, class names, variable names, and the like. In your code, whitespace does not really matter. You can add space here and here, and you would still get the same output. However, in case of strings, whitespace does matter. If we say print("hellO World"), it would print "hellO World", with a space in between. And if you do print("hellO World") with three spaces, it would print the same. In expressions, white-space does not affect the output. >>> print ( "hellO World" ) hellO World >>> print ( "hellO World" ) hellO World The last thing we want to look at, is an escape sequence. Let's say you want to print a double quote, ", in the code. If we were to do this: print("Hello""), what would happen? The compiler says error! >>> print("Hello"") File "<stdin>", line 1 print("Hello"") ^ SyntaxError: EOL while scanning string literal If you want to print a " inside a string, use an escape sequence. In Python, the symbol '\' is used as an escape character. On using '\' adjacent to the ", it prints Hello" (notice the trailing "). We have used the '\' to escape the ", by forming an escape sequence \".>>> print("Hello\"")Hello">>> The other reason why you would want to use a '\' is to print a <NEWLINE>. If you want to print "Hello World", but with "Hello" on one line and "World" on the next, '\n' is the escape sequence to use. >>> print("Hello\nWorld") Hello World The other important escape sequence is '\t', which prints a <TAB> in the output. When you do print("Hello\tWorld"), you can see the tab-space between "Hello" and "World". >>> print("Hello\tWorld") Hello World Another useful escape sequence is \\ . If you want to print a \ , then use the sequence \\ . You would see that it prints Hello\World . Think about what would happen if we put six \ . Yes you're right! It would print this string: "\\\" . >>> print("Hello\\World") Hello\World >>> print("Hello\\\\\\World") Hello\\\World One of the things with Python is, it does not matter whether you use double quotes or single quotes to enclose strings. There are some interesting, and useful ways of using a combination of both, within the same string. Have a look at this call: print("Hello'World"), and notice the output we get. In a similar way, the following code will be accepted and run by the Python system: print('Hello"World'). >>> print('Hello"') Hello" >>> print("Hello'World") Hello'World >>> print("Hello\"World") Hello"World >>> print("Hello\"World") Hello"World The above two examples can be used as a tip by newbie programmers when they form string literals, and want to use them in their code: If the string literal contains one or more single quotes, then you can use double quotes to enclose it. However if the string contains one or more double quotes, then prefer to use single quotes to enclose it. Summary In this step, we: Explored a number of puzzles related to code involving: Built-in functions for numeric calculations The print() function to display expressions and strings Covered the following aspects of the above utilities: Case-sensitive aspects of names and strings The role played by whitespace The escape character, and common escape sequences Step 08: Formatted Output With print() In the previous step, we learned how to print a hard-coded string, such as "5 * 6 = 30". In this step, let's try to replace the hard-coded 30 with a computed value. Let's start with a simple scenario. Let's say we want to place that calculated value within a string, and display it. How do we do that? Snippet-01: print() Formatted Output format() method can be used to print formatted text. Let's see an example: >>> print("VALUE".format(5*2)) VALUE We were expecting 10 to be printed, but it's actually printing VALUE. How do we get 10 to be printed then? >>> print("VALUE {0}".format(5*2)) VALUE 10 By having an open brace {, closed brace }, and and by putting the index of the value between them. Here, the value is the first parameter, and it's index will be 0."VALUE {0}" is what we need. Let's take another example. Suppose to the format() function, we pass three values: 10, 20 and 30. Typically when we count positions or indexes, we start from 0. To print the first value, you need to pass in an index of 0. To print the second value, pass an index of 1. >>> print("VALUE {0}".format(10,20,30)) VALUE 10 >>> print("VALUE {1}".format(10,20,30)) VALUE 20 >>> print("VALUE {2}".format(10,20,30)) VALUE 30 Now going back to our problem, we wanted to display "5 * 6 = 30", but without hard-coding. Instead of 30, we want the calculated value of 5 * 6. >>> print("5 * 6 = 30".format(5,6,5*6)) 5 * 6 = 30 Let replace "5 * 6 = 30" with "5 * 6 = {2}". 2 is the index of parameter value 5*6. >>> print("5 * 6 = {2}".format(5,6,5*6)) 5 * 6 = 30 Cool! Progress made. Let's replace 5 * 6 with the right indices - {0} * {1}. >>> print("{0} * {1} = {2}".format(5,6,5*6)) 5 * 6 = 30 The great thing about this, is now we can replace the values we passed to print() in the first place, without changing the indexes! So, we can display results for 5 * 7 = 35 and 5 * 8 = 40. We are now able to print 5 * 6 = 30, 5 * 7 = 35, 5 * 8 = 40, and can do similar things for other table entries as well. >>> print("{0} * {1} = {2}".format(5,7,5*7)) 5 * 7 = 35 >>> print("{0} * {1} = {2}".format(5,8,5*8)) 5 * 8 = 40 >>> print("{0} * {1} = {2}".format(5,8,5*8)) 5 * 8 = 40 Summary In this step, we: Discovered that Python provides a way to do formatted printing of string values Looked at the format() function, and saw how to call it within print() Observed how we could work only with the indexes of parameters to format(), and change the parameters we pass without changing the code Step 09: Puzzles On format() and print() In this step, let's look at a few puzzles related to the format, and the print methods. Snippet-01: format() And print() Puzzles Let's say we pass in additional values, such as: 5 * 8, 5 * 9 and 5 * 10. However, within the call to format(), we are only referring to the values at index 0, index 1 and index 2. The values at indexes 3 and 4 are not used at all. What would happen when we run the code? >>> print("{0} * {1} = {2}".format(5,8,5*8,5*9,5*10)) 5 * 8 = 40 Would this throw an error? No, it does not. You can see that the additional values which are passed in, are conveniently ignored. Let's say instead of passing in a value of 2, we pass 4. What would happen? >>> print("{0} * {1} = {4}".format(5,8,5*8,5*9,5*10)) 5 * 8 = 50 5 * 10 is the value at index 4 Now let's take a different scenario. We remove all the parameters passed to format(). However, inside the call to print(), we continue to say {0} * {1} = {4}. So we are trying to print the value at index 4, but are only passing two values to the function format(). What do you think will happen? >>> print("{0} * {1} = {4}".format(5,8)) Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: tuple index out of range It says IndexError, which means :“you are asking me to fetch the value at index 4, but only passing in two values. How can I do what you want?” Let's look at a few more things related to other data types. We try to format the following inside print(): {0} * {1} = {2}, and would pass in 2.5, 2, and 2.5 * 2 . Here, 2 is an integer value, but 2.5 is a floating point value. You can see that it prints 2.5 * 2 = 5.0. So this approach of formatting values with print(), works also with floating point data as well. >>> print("{0} * {1} = {2}".format(2.5,2,2.5*2)) 2.5 * 2 = 5.0 Now, are there are other types of data that format() works with? Yes, strings can join the party. Let's say over here, we do: print("My name is {0}".format("Ranga")). What would happen? >>> print("My name is {0}".format("Ranga")) My name is Ranga Index 0 will be replaced with the first parameter to format(). Summary In this step, we: Understood the behavior when the parameters passed to format(): Exceed the indexes accessed by print() Are less than the indexes accessed by print() Are of type integer, floating-point or string Step 10: Introducing Variables We are slowly making progress toward our main goal, which is to print the 5 multiplication table. In the first statement, we are printing 5 * 1 = 5, and then changing the literals. To make it print 5 * 2 = 10, we are changing 1 to 2. Next, we are changing 2 to 3. How do we make it a little simpler, so that our effort is reduced? >>> print("{0} * {1} = {2}".format(5,1,5*1)) 5 * 1 = 5 >>> print("{0} * {1} = {2}".format(5,2,5*2)) 5 * 2 = 10 >>> print("{0} * {1} = {2}".format(5,3,5*3)) 5 * 3 = 15 Let's try a different approach. What would happen if you replace 1 with index, and 5 * 1 with 5 * index, and try to run it? It gives an error! It says: “index is not defined”. Let's try and fix this, and execute index = 2. What would happen? >>> index = 2 Aha! This compiles. >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 2 = 10 And this statement is printing 5 * 2 = 10. Let's try something else. Let's make index = 3. What would happen? >>> index = 3 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 3 = 15 The same statement on being run, prints 5 * 3 = 15. How can you check the value that index has? Just type in index. >>> index 3 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 3 = 15 The index symbol we have used here, is what is called a variable. In Python, it's also called a name. You can see that the value index referring to, can change over the duration of a program. Initially, index was referring to a value of 1. later, index was referring to a value of 3. Now, think about how you would print the entire table. All that you need to do, is start from 1, execute the same statement with print() and format(), to get output 5 * 1 = 5. Next, Change the value of index to 2, and then print the same statement. Next, index = 3, and print the same statement again. >>> index = 1 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 1 = 5 >>> index = 2 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 2 = 10 >>> index = 3 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 3 = 15 With the same statement print("{0} * {1} = {2}".format(5,index,5*index)), we are able to print different values. The value of index varies, but the code remains the same! Variables make the program much more easier to read, as well as more generic. Snippet-02: Classroom Exercise On Variables Let's do a simple exercise with variables. We want to create three variables a, b and c. Let's initially give them some values, say a value of 5 to a, 6 to b and 7 to c. We want to get output of this kind: 5 + 6 + 7 = 18, without using the literal values. You would want to use the values stored in the variables in a, b and c. If you're hard-coding, the way to do it is with print("5 + 6 + 7 = 18"). >>> a = 5 >>> b = 6 >>> c = 7 >>> print("5 + 6 + 7 = 18") 5 + 6 + 7 = 18 >>> print("5 + 6 + 7 = 18".format(a,b,c,a+b+c)) 5 + 6 + 7 = 18 The way you can do that is with code like this: print("{0} + {1} + {2} = {3}".format(a,b,c,a+b+c)). >>> print("{0} + {1} + {2} = {3}".format(a,b,c,a+b+c)) 5 + 6 + 7 = 18 How do you confirm we are accessing values stored in the variables? Let's change the values of a, b and c. Let's make a = 6 , b = 7 , and c = 8 . Execute same statement. >>> a = 6 >>> b = 7 >>> c = 8 >>> print("{0} + {1} + {2} = {3}".format(a,b,c,a+b+c)) 6 + 7 + 8 = 21 You can see the magic of variables at play here! Based on what values these variables are referring to, you can see that the output of the print statement changes. Summary In this step, we: Were introduced to variables, or names, in Python Observed how we could pass in values of variables to the format() function Step 11: Puzzles On Variables In the previous step, we were introduced to the concept of variables in Python. We will start with looking at a few puzzles. Snippet-01: Puzzles On Variables What if I try to refer to a variable which is not yet created? >>> count Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'count' is not defined >>> print(count) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'count' is not defined Before using a variable, you need to have it assigned a value. If you have not defined a variable before, then you cannot use it. Consider print(count), it does not know what count is. So it would throw an error, saying: “ count is not defined, I have no idea what count is.” Once you assign a value to a variable, you can use it. >>> count = 4 >>> print(count) 4 The statement count = 4 where we are creating a variable named count for the first time, is called a variable definition. This is the first time you're referring to a variable, and assigning a value to it. Python will create a variable in its memory. Variable names are case sensitive. count and Count are not the same thing. >>> Count Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Count' is not defined >>> count 4 There are rules to follow while naming variables. All variable names should either start with an alphabet , or an underscore _ . count, _count are valid. 1count is invalid. >>> 1count = 5 File "<stdin>", line 1 1count = 5 ^ SyntaxError: invalid syntax >>> count = 5 >>> _count = 5 >>> 1count File "<stdin>", line 1 1count ^ SyntaxError: invalid syntax >>> 2count File "<stdin>", line 1 2count ^ SyntaxError: invalid syntax After the first symbol, you can also use a numeral in variable names. >>> c12345 = 5 To summarize the rules for naming variables. This should start with an alphabet (a capital or a small alphabet) or underscore. Starting the second character, it can be alphabet, or underscore, or a numeric value. Summary In this step, we: Understood that a variable needs to be defined before it is used Learned that there are certain rules to be followed while giving names to variables Step 12: Introducing Assignment In this step, we will look at an important concept in Python, called assignment. In previous steps, we created variables, like i = 5. Snippet-01: Introducing Assignment You can create other variables using whatever value i is referring to. If we say j = i, what would happen? >>> i = 5 >>> j = i >>> j 5 j would start referring to the same value that i is referring to. This statement is called an assignment. Let's try j = 2 * i. >>> j = 2 * i >>> j 10 j refers to a value of 10= has a different meaning in programming compared to mathematics. In mathematics, When we execute j = i, it means j and i are equal. In prgramming, the value of the expression on right hand side is assigned to the variable on the right hand side. Can you use a constant on the left hand side of an assignment? The answer is “No”! >>> 5 = j File "<stdin>", line 1 SyntaxError: can't assign to literal The Python Shell throws an error, saying “Can't assign to literal”, as 5 is a literal. Let's create a couple of variables. num1 = 5 and num2 = 3. We would want to add these and create a fresh variable. Let's say the name of the variable is sum. >>> num1 = 5 >>> num2 = 3 >>> sum = num1 + num2 >>> sum 8 Create 3 variables a, b and c with different values and calculate their sum. >>> a = 5 >>> b = 6 >>> c = 7 >>> sum = a + b + c >>> sum 18 We have just seen the mechanics of how assignment works in Python. Summary In this step, we: Learned what happens when you assign a value to a variable, which may or may not exist Discovered that literal constants cannot be placed on the left hand side of the assignment(=) operator Step 13: Introducing Formatted Printing Until now, we have been using the format() method to format and print values. Let's see a better approach to printing values. This is the approach we used until now. >>> a = 1 >>> b = 2 >>> c = 3 >>> sum = a + b + c >>> print("{0} + {1} + {2} = {3}".format(a, b, c ,sum)) 1 + 2 + 3 = 6 Python has the concept of formatted strings. The syntax to use a formatted string is very simple - f"". If we want to print the value of a variable a, we can use {a} in the text. >>> print(f"") >>> print(f"value of a is {a}") value of a is 1 >>> print(f"value of b is {b}") value of b is 2 The variable within braces is replaced by its value. You can use expressions in a formatted string. Example below uses {a+b}. >>> print(f"sum of a and b is {a + b}") sum of a and b is 3 This feature was introduced in a Python 3 release. Let's get back to the original problem we wanted to solve: printing 5 + 6 + 7 = 18, using formatted strings. >>> print(f"{a} + {b} + {c} = {sum}") 1 + 2 + 3 = 6 You can see how easy it turns out to be! Step 14: The PMT-Challenge Revisited We want to print the 5-table from 5 * 1 = 5 onward, until we reach to 5 * 10 = 50. The best solution we have right now, is shown below: Snippet-01: >>> index = 1 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 1 = 5 >>> index = 2 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 2 = 10 >>> index = 3 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 3 = 15 >>> index = 4 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 4 = 20 Can we do something, to make sure that the code remains the same all the time, but the index value gets updated? >>> index = index + 1 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 5 = 25 >>> index = index + 1 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 6 = 30 >>> index = index + 1 >>> print("{0} * {1} = {2}".format(5,index,5*index)) 5 * 7 = 35 We used index = index + 1 to increment index value. If we execute these same two statements again and again, we can print the entire table! This is exactly what loops help us do: execute the same statements repeatedly. The simplest loop available in Python is the for loop. When we run a for loop, we need to specify the range of values - 1 to 10 or 1 to 20, and so on. range() function helps us to specify a range of values. >>> range(1,10) range(1, 10) The syntax of the for loop is: for i in range(1, 10): .... Here, i is the name of the control variable. In Python, you need to put a colon, ':', and in the next line give indentation. >>> for i in range(1,10): ... print(i) ... 1 2 3 4 5 6 7 8 9 You would see that it prints from 1 to 9. When we run a loop in range(1, 10), 1 is inclusive and 10 is exclusive.The loop runs from 1 to the value before 10, which is 9. The leading whitespace before print(i) is called indentation. We'll talk about indentation later, when we talk about puzzles related to the for loop. How can you extend this concept to solving our PMT-Challenge problem? >>> print(f"{5} * {index} = {5*index}") 5 * 7 = 35 What we were doing earlier, was calling print() with a formatted string. Now we want to print this statement for different values of i. How can you do that? Let's start with a simple example. >>> for i in range(1,11): ... print(f"{i}") ... 1 2 3 4 5 6 7 8 9 10 print(f"{i}") prints the value of i. Now, how do we get it to print 5 * 1 = 5 to 5 * 10 = 50? >>> for i in range(1,11): ... print(f"5 * {i} = {5 * i}") ... 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 5 * 8 = 40 5 * 9 = 45 5 * 10 = 50 >>> 5 * 4 * 50 1000 print(f"5 * {i} = {5 * i}") prints a specific multiple of 5. Step 15: Loops In a previous step, we took a major step in programming. We wrote our first for loop with Python. In this step, let's try a few puzzles to understand the for loop even further. The syntax of the for loop we looked at earlier was: for i in range(1, 10): print(i) Snippet-01: Let's say we write a for loop, but don't give a : after the range() method, to close the first line. What would happen? >>> for i in range(1,10) File "<stdin>", line 1 for i in range(1,10) ^ SyntaxError: invalid syntax Invalid syntax. A : is mandatory within the for loop syntax. Let's provide a : and in the next line, use print(i) without space before it (without indentation). >>> for i in range(1,10): ... print(i) File "<stdin>", line 2 print(i) ^ IndentationError: expected an indented block Most other programming languages use open brace { and closed brace } as delimiters in a for loop. However, Python uses indentation to identify which code is part of a for loop, and which is not. So if we are writing the body of a for loop, we must use indentation, and leave atleast a single <SPACE>. >>> for i in range(1,10): ... print(i) ... 1 2 3 4 5 6 7 8 9 How do we execute two lines of code as part of the for loop? >>> for i in range(1,10): ... print(i) ... print(2*i) ... 1 2 2 4 3 6 4 8 5 10 6 12 7 14 8 16 9 18 We are indenting both statements with a space - print(i) and print(2*i). When for loop has only one line of code, you can specify it right after the : >>> for i in range(2,5): print(i) ... 2 3 4 However, this is not considered to be a good programming practice. Even though you may want to execute just one statement in a for loop, indentation on a new line is recommended. Another best practice is to use four <SPACE> s for indentation, instead of just two. This would give clear indentation of the code. >>> for i in range(2,5): ... print(i) ... 2 3 4 Anybody who looks at the code immediately understands that this print() is part of the for loop. Let's say you only want to print the odd numbers till 10, which are 1, 3, 5, 7 and 9. The range() function offers an interesting option. >>> for i in range (1,11,2): ... print(i) ... 1 3 5 7 9 In for i in range(1, 11, 2), we pass in a third argument, called a step. After each iteration, the value of i is increment by step. Summary In this step, we: Looked at a few puzzles about the for loop, which lay emphasis on the following aspects of for: The importance of syntax elements such as the colon Indentation Variations of the range() function Step 16: Programming Exercise PE-BA-02 In the previous step, after initially exploring the Python for loop, we looked at a number of puzzles. In this step, let's look at a few exercises. Exercises Print the even numbers up to 10. We would want to print 2 4 6 8 10, using a for loop. Print the first 10 numbers in reverse Print the first 10 even numbers in reverse Print the squares of the first 10 numbers Print the squares of the first 10 numbers, in reverse Print the squares of the even numbers Solution 1 Instead of starting with 1, we need to start with 2. Each time, i it would be incremented by 2, and 2 4 6 8 and 10 would be printed. >>> for i in range (2,11,2): ... print(i) ... 2 4 6 8 10 Solution 2 We would want to print the numbers in reverse. Think about how you would do that using the range() function. We'd want go from 10, 9, 8, and so on up to 1. >>> for i in range (10,0,-1): ... print(i) ... 10 9 8 7 6 5 4 3 2 1 The value to start with is 10. As we discussed earlier, the end value is exclusive. So to print from 10 to 1, we want to end one value which is 0. range(10, 0) seems to be what we need. Usually these step value is positive, but we need to go backwards from 10. Hence, we would give a step value of -1. Solution 3 Now, let's print the first 10 even numbers in reverse. >>> for i in range (20,0,-2): ... print(i) ... 20 18 16 14 12 10 8 6 4 2 Solution 4 Next, we would want to print the squares of the first 10 numbers. >>> for i in range (1,11): ... print(i * i) ... 1 4 9 16 25 36 49 64 81 100 Solution 5 Let's print the squares in the reverse order. >>> for i in range (10,0,-1): ... print(i*i) ... 100 81 64 49 36 25 16 9 4 1 Solution 6 Print the squares of the even numbers. How to do that? >>> for i in range (10,0,-2): ... print(i*i) ... 100 64 36 16 4 The key part is using a step of -2 We leave it as an exercise for you, to print squares of odd numbers. Summary In this video, we: * Tried out a few exercises involving the for loop, by playing around with printing sequences of numbers. Used the for loop to simplify the solution to the PMT-Challenge problem. Step 17: Review: The Basics Of Python It must have been a roller-coaster ride to solve the multiplication table challenge so far. If you're new to programming, there are a wide range of topics and concepts, that you would have learned during this small journey. Let's quickly revise the important concepts we have learned during this small journey. 1, 11, 5, … are all called literals because these are constant values. Their values don't really change. _Consider 5 _ 4 _ 50`. This is an expression. `_`is an operator, and`5`, `4`and`50 are operands. The name i in i = 1, is called a variable. It can refer to different values, at different points in time. range() and print() are in-built Python functions. Every complete line of code is called statement. The specific statement print(), is invoking a method. The other statement which we looked at earlier, was an assignment statement. index = index + 1 would evaluate index + 1, and have the index variable refer to that value. The syntax of the for loop was very simple. for var in range(1, 10) : ..., followed by statements you would want to execute in a loop, with indentation. For the sake of indentation we left four <SPACE> s in front of each statement inside the for loop. So that, in a nutshell, is what we have learned over the course of our first section. Chapter 03 - Introducing Methods In the last section, we introduced you to the basics of python. We learned those concepts by applying them to solve the PMT-Challenge problem. The code below is what we ended up with as we solved that chellenge. Snippet-01: Current Solution To PMT-Challenge >>> for i in range (1,11): ... print(f"8 * {i} = {8 * i}") If we wanted to change the code to print the 7 table, we need to change the value 7 used in the for loop, to 8. It's simple, but still not as friendly as you would like. >>> for i in range (1,11): ... print(f"7 * {i} = {7 * i}") To print a 7 table, it would be awesome if could say print_multiplication_table, and give a value of 7 beside it, and it would do the rest: >>> print_multiplication_table(7) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'print_multiplication_table' is not defined >>> print_multiplication_table(8) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'print_multiplication_table' is not defined Similarly, print_multiplication_table(8), could print the multiplication table for 8! To be able to do this, we need to create a method, or a function. Creating a method makes the code reusable, and we can invoke that method very easily by passing arguments. In this section, we take an in-depth look at methods. Step 01: Defining Your First Method Methods are very important building blocks in Python programming. In this step, we will create a simple method that prints "Hello World", twice. Snippet-01: When we talk about a method, we need to give it a name. We are already using an in-built Python method here, which is print(). >>> print("Hello World") Hello World >>> print("Hello World") Hello World Similar to that, we need to give a name to our body of code. Let's say the name is print_hello_world_twice. The syntax to create a method in Python is straightforward: At the start, use the keyword def followed by a space. Followed by name of the method - print_hello_world_twice. Add a pair of parenthesis: (). This is followed by a colon : (similar to what we used in a for loop).>>> def print_hello_world_twice():... print("Hello World")... print("Hello World")... All statements in a method should be indented. The two print("Hello World") are indented. So, they are part of the method body. print_hello_world_twice() defines a method, and it has certain code inside its body. How do we call this method? Is it sufficient to say print_hello_world_twice? >>> print_hello_world_twice <function print_hello_world_twice at 0x10a71ef28> Python Shell says, there's a function defined with that specific name. How do we execute a method? Very simple! Add a pair of parentheses to the name, ()! >>> print_hello_world_twice() Hello World Hello World >>> print_hello_world_twice() Hello World Hello World Now, we are able to run the method. Summary In this step, we: Learned we can define our own methods in the code we write Understood how to define a method, and all its syntax elements Saw how we can invoke a method we write Step 02: Programming Exercise PE-MD-01 We will now leave you with two exercises, based on what we have learned about methods so far. Exercises Write a method called print_hello_world_thrice(). It should print "Hello World" thrice to the output. Define this method, and also invoke it. Write and execute a method, that prints four statements:“I have created my first variable.”“I've created in my first loop.”“I've created my first method.”“I am excited to learn Python.” You need to print these four statements on four consecutive lines. Solutions Solution 1 >>> def print_hello_world_thrice(): ... print("Hello World") ... print("Hello World") ... print("Hello World") ... >>> print_hello_world_thrice() Hello World Hello World Hello World Solution 2 >>> def print_your_progress(): ... print("Statement 1") ... print("Statement 2") ... print("Statement 3") ... print("Statement 4") ... >>> print_your_progress() Statement 1 Statement 2 Statement 3 Statement 4​ def print_your_progress(): print("Statement 1") print("Statement 2") print("Statement 3") print("Statement 4") For convenience, we have changed the exact text we need to print. Call this method with the syntax print_your_progress(), and you're able to execute its code. Now try another exercise. We want to print "Statement 1", "Statement 2", "Statement 3" and "Statement 4" on different lines, using just one print statement. How can you do that? >>> def print_your_progress(): ... print("Statement 1\nStatement 2\nStatement 3\nStatement 4") ... >>> print_your_progress() Statement 1 Statement 2 Statement 3 Statement 4 We are using the newline character \n. Let's look at the difference between defining and executing a method. When we are writing a method definition, we are writing the code as part of its body. It has a specific syntax, and starts with the def keyword. A definition by itself cannot cause the code in its body to be executed. print_your_progress() represents a method call. The code inside the method is executed. Summary In this step, we: Implemented solutions to a few exercises that test our understanding of Python methods. We touched concepts such as: Defining a method body The way to invoke a method, to run its code The difference between the two Step 03: Passing Parameters To Methods In the previous step,we created methods. We defined print_hello_world_twice(), and this printed "Hello World" twice. In this step, let's talk about method arguments, or parameters. Snippet-01: >>> print_hello_world_twice() Hello World Hello World >>> print_hello_world_thrice() Hello World Hello World Hello World Earlier, we wrote code for print_hello_world_thrice(), which prints the message three times. Let's say you want to print it five times. You would need to write another method that does what you need. Doesn't that seem monotonous? Instead of that, Won't it be great if I can call the method by the same name, say print_hello_world(5), and it would print “Hello World” five times? The 5 which we are passing here is called an argument. How do we define our method to accept this argument? Let's call our argument no_of_times. If you have any experience with other programming languages, they generally need you to specify the parameter type. Something like This parameter is an integer/float/string, or other types. But Python does not require parameter type. >>> def print_hello_world(no_of_times): ... print("Hello World") ... print(no_of_times) ... Although we are not doing exactly what we set out to, let's see what would happen. What would happen if we say print_hello_world() ? >>> print_hello_world() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: print_hello_world() missing 1 required positional argument: 'no_of_times' Error! Something like “Hey, you have created print_hello_world with a parameter, but not passing anything in here! Go ahead and pass a value”. Let's pass in a value, such as 5. >>> print_hello_world(5) Hello World 5 >>> print_hello_world(10) Hello World 10 >>> print_hello_world(100) Hello World 100 With print_hello_world(5), you can see "Hello World" and 5 being printed. We are now able to define this method to accept a value, and print that value by invoking it. You can pass in any value, such as 10, 100, or others. Now think of a different solution for this method, where you don't repeat the same piece of code to print "Hello World". Consider print_hello_world(5), it should still print "Hello World" 5 times. How do you do that? Think about using something along the lines of a loop. Snippet-02: For now, what we are doing is we are printing "Hello World" 10 times. >>> def print_hello_world(no_of_times): ... for i in range(1,10): ... print("Hello World") ...​ >>> print_hello_world(5) Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Hello World Our method call print_hello_world(5) now prints "Hello World" 10 times. However just print the message 5 times. We need to make use of the parameter no_of_times inside the for loop as well. >>> def print_hello_world(no_of_times): ... for i in range(1,no_of_times): ... print("Hello World") ...​ >>> print_hello_world(5) Hello World Hello World Hello World Hello World Now let's execute the method again. You can see that it's printing 4 times only. Why is it not printing 5 times? That's because no_of_times as a second parameter to range() is exclusive. >>> def print_hello_world(no_of_times): ... for i in range(1,no_of_times+1): ... print("Hello World") ... >>> print_hello_world(5) Hello World Hello World Hello World Hello World Hello World Great, it's now printing the message 5 times! >>> print_hello_world(7) Hello World Hello World Hello World Hello World Hello World Hello World Hello World If you pass a different argument like 7, the message is displayed 7 times. Something you need to always be cautious about in Python, is the indentation. Over here, the for loop is part of the method body. So we have extra indentation for it. The print is part of the for loop body. So guess what, even more indentation for that code. Summary In this step, we: Learned how to pass arguments to a method Understood that the method definition needs to have parameters coded in Observed that arguments passed during a method call can be accessed inside a methods body Step 04: Classroom Exercise CE-MD-01 In this step, Let's look at a few exercises related to the method parameter. Exercises Write a method called print_numbers(), that would print all successive integers from 1 to n. The second one is to write a method called print_squares_of_numbers(), that prints squares of all successive integers from 1 to n. Solutions Solution 1 >>> def print_numbers(n): ... for i in range(1, n+1): ... print(i) ... >>> print_numbers(5) 1 2 3 4 5 >>> If you are programming in other languages such as Java, you are used to naming methods in this way: printNumbers(). This convention is popularly known as “Camel Case”. That's NOT how Python programmers name their methods. Pythonic way is to use underscore _ to separate words in the method name, as in print_numbers(). Solution 2 Let's define print_squares_of_numbers(). This would be very similar to print_numbers(), working with the same range. Only, we need to say print(i*i) . >>> def print_squares_of_numbers(n): ... for i in range(1, n+1): ... print(i*i) ... >>> print_squares_of_numbers(5) 1 4 9 16 25 How is a parameter different from an argument? Inside the definition of the method, the name within parentheses is referred to as a parameter. In our recent exercise, n is a parameter, because it's used in the definition of print_squares_of_numbers. When you are passing a value to a method during a method call, say 5, that value is called an argument. Don't worry too much about it. Just follow this convention for now: In the method call, call it an argument. In a method definition, call it a parameter. Summary In this step, we looked at a few simple exercises related to passing method arguments Step 05: Methods With Multiple Parameters In this step, let's look at creating a method with multiple parameters. Snippet-01: print_hello_world accepts one parameter and prints “Hello World” the specified number of times. >>> def print_hello_world(no_of_times): ... for i in range(1,no_of_times+1): ... print("Hello World") ... Let's say we want to print another piece of text Welcome To Python, a specified number of times. How do you do that? You can always create another method similar to the first one, such as print_welcome_to_python(no_of_times) and print the necessary text inside. However, is that what a good programmer does? A good programmer tries to create a more generic solution. >>> def print_string(str, no_of_times): ... for i in range(1,no_of_times+1): ... print(str) ... >>> print_string("Hello World", 3) Hello World Hello World Hello World The good programmer that you are, you created a new method called print_string(str, no_of_times) accepting a text parameter, in addition to no_of_times. Syntax rules for method parameters are quite strict. If we say print_string("Welcome to Python") and run it, we get an error! Python Shell says: “I need no_of_times to be present in here”. >>> print_string("Welcome to Python") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: print_string() missing 1 required positional argument: 'no_of_times' Let's say you want to assign default values for str and no_of_times in print_string(). By default, we want to always print "Hello World", and that too 5 times. The Python language makes this very easy. def print_string(str = "Hello World", no_of_times=5). The rest of the method remains the same. >>> def print_string(str="Hello World", no_of_times=5): ... for i in range(1,no_of_times+1): ... print(str) ... Now you can call print_string(), and "Hello World" is displayed 5 times. >>> print_string() Hello World Hello World Hello World Hello World Hello World If it's print_string("Welcome To Python"), what does it do? It prints "Welcome To Python", 5 times. >>> print_string("Welcome to Python") Welcome to Python Welcome to Python Welcome to Python Welcome to Python Welcome to Python Consider print_string("Welcome to Python", 8), it would print that string 8 times. >>> print_string("Welcome to Python", 8) Welcome to Python Welcome to Python Welcome to Python Welcome to Python Welcome to Python Welcome to Python Welcome to Python Welcome to Python Isn't that cool! Summary In this step, we: Looked at how to pass multiple parameters to a method, starting with two arguments Learned how you can define default values for those parameters Observed we could pass default arguments for none, some or all of those parameters Step 06: Back To Multiplication Table - Using Methods Let's get back to our original goal, of why we needed methods. We wanted to create a multiplication table for a number, and observed that each time we needed to we needed change that number, we were forced to make a change in the code. This is not something we liked, and that's why we started investigating how methods can be used. In this step, Let's try our hand at creating a multiplication table method. Snippet-01: >>> for i in range (1,11): ... print(f"7 * {i} = {7 * i}") Let's define a method called print_multiplication_table(), and pass in a parameter to it. >>> def print_multiplication_table(table): ... for i in range(1,11): ... print(f"{table} * {i} = {table * i}") ... >>> print_multiplication_table(7) 7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49 7 * 8 = 56 7 * 9 = 63 7 * 10 = 70 Now you have the entire multiplication table for 7. You can then call print_multiplication_table() with arguments 8, 9,and so on, by simply changing the table arguemnt value. We now want to create even better print_multiplication_table() method. We want to control the start point, as well as the end point, in the call to range(). We want to say print_multiplication_table(7, 1, 6), to print the 7 table with entries from 1 to 6. How can you do that? >>> def print_multiplication_table(table, start, end): ... for i in range(start, end+1): ... print(f"{table} * {i} = {table * i}") ... >>> print_multiplication_table(7, 1 , 6) 7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 Simple! Define those range limits as additional parameters! The other thing we can obviously do, is have default values for the start, and the end. >>> def print_multiplication_table(table, start=1, end=10): ... for i in range(start, end+1): ... print(f"{table} * {i} = {table * i}") ...​ >>> print_multiplication_table(7) 7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49 7 * 8 = 56 7 * 9 = 63 7 * 10 = 70 Calling print_multiplication_table(7) would give us entries from 7 * 1 = 7 to 7 * 10 = 70. Now you can actually send out this method, to your friends, who would find it easy to use, and cool! Summary In this step, we: Learned how to define a method to print the multiplication table for a number Looked at how to enhance this method to make table printing more flexible Further enhanced that method to accept default arguments while printing a table Step 07: Indentation Is King In Python, indentation denote blocks of code. So if you want to put something in a for loop, or outside it, proper indentation would be sufficient. In this step, let's explore indentation in depth. Let's start by creating a simple method. Snippet-01: >>> def method_to_understand_indentation(): ... for i in range(1,11) : ... print(i) ... >>> method_to_understand_indentation() 1 2 3 4 5 6 7 8 9 10 Consider the code below: print(5) is indented at the same level as for loop. >>> def method_to_understand_indentation(): ... for i in range(1,11) : ... print(i) ... print(5) ... You can see that print(5) is called only once. It is not part of the for loop. >>> method_to_understand_indentation() 1 2 3 4 5 6 7 8 9 10 5 Let's change the code in this method a bit. print(5) is indented the same way as print(i) >>> def method_to_understand_indentation(): ... for i in range(1,11) : ... print(i) ... print(5) ... print(5) is part of the for loop. It is executed 10 times. >>> method_to_understand_indentation() 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 5 10 5 Whether we're talking about loops, methods or conditionals, proper indentation is very important in Python. We indicate a block of code, by having all lines of that block at the same indentation level. There are no specific delimiters like for instance a pair of braces {...}, as in other programming languages. Summary In this step, we: Ran through a few examples to see how indentation works in Python Step 08: Puzzles on Methods - Named Parameters In this step, let's look at a variety of puzzles related to methods. Snippet-01: Consider the following method: I would want to print the default string 6 times. How do we do it? >>> def print_string(str="Hello World", no_of_times=5): ... for i in range(1,no_of_times+1): ... print(str) ... >>> print_string() Hello World Hello World Hello World Hello World Hello World Will it work if we call the method as in: print_string(6)? >>> print_string(6) 6 6 6 6 6 6 is passed as the first parameter. 6 is matched to str, and the method prints 6 the default number of times, which is 5. to default to "Hello World", and print it 6 times. You can do this in Python by using named parameters. During the method call, you can specify no_of_times = 6. no_of_times is a named parameter. There is no provision of doing something like this, in other languages like Java. Call it as print_string(no_of_times=6): >>> print_string(no_of_times=6) Hello World Hello World Hello World Hello World Hello World Hello World str gets a default value, and "Hello World" is printed 6 times. Named parameters are very useful, when a method has a number of parameters, and you would want to make it very clear which parameter you're passing a value for. Let's call print_string(7, 8). what happens? >>> print_string(7, 8) 7 7 7 7 7 7 7 7 You would see that 7 is printed 8 times. Since print() method is quite flexible, you can pass a number as the first argument. You can even pass a float. >>> print_string(7.5, 8) 7.5 7.5 7.5 7.5 7.5 7.5 7.5 7.5 What would be the result of this - print_string(7.5, "eight")? >>> print_string(7.5, "eight") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in print_string TypeError: must be str, not int Note how no_of_times is used inside the method… as an argument to range(). range() only accepts integers, nothing else. When you run the code with print_string(7.5, "eight"), we get an error. It says: TypeError: ```no_of_times``` must be ```int```, not string. A simple rule of thumb is, if you have a parameter, you can pass any type of data to it. That could be an integer, a floating point value a string, or a boolean value. The Python language does not check for the type of a parameter. However, Python will throw an error if the function which is using that parameter, expects it to be of a specific type. The range() function expects that the no_of_times is an integer value. Snippet-02: The last thing which we would be looking at, is method naming conventions. We named our methods in a consistent way: print_string, print_multiplication_table, and the like. This is exactly the format which most Python developers use, to name their methods. Convention is to use underscore to separate words in a name. However, there are a few rules for naming a method: One of the important rules is also related to variable names. We observed that a variable name cannot start with a number. >>> def 1_print(): File "<stdin>", line 1 def 1_print(): ^ SyntaxError: invalid token Similarly, 1_print will not be accepted as a method name. You can start a name with an alphabet, or with an underscore. From the second character onward, you are allowed to use numeric symbols. Methods and variables cannot be named using Python keywords. Now, what is a keyword? For example, when we talked about for loop, as in:```for i in range(1, 11): print(i)```... for is a keyword in is a keyword def is a keyword. Later we will look at a few other keywords, such as while, return, if, else, elif, and many more. >>> def def(): File "<stdin>", line 1 def def(): ^ SyntaxError: invalid syntax >>> def in(): File "<stdin>", line 1 def in(): ^ SyntaxError: invalid syntax >>> def for(): File "<stdin>", line 1 def for(): ^ SyntaxError: invalid syntax Summary In this step, we: Were introduced to the concept of named parameters Explored the typical naming rules and conventions for methods in Python Observed that reserved keywords cannot be used to name variables or methods Step 09: Methods - Return Values Let's try and understand the importance of return values from a method. We will learn how to return a value from a method. Snippet-01: Let's name our method as product_of_two_numbers(), and let's have parameters a and b that it accepts: >>> def product_of_two_numbers(a,b): ... print(a * b) ... >>> product_of_two_numbers(1,2) 2 Can we take the product of these two numbers into a variable, and use it in other code, in the same program? Suppose we say a product = product_of_two_numbers(1,2), is this allowed? Let's run this code, and see what's stored in product. >>> product = product_of_two_numbers(1,2) 2 >>> product It's empty. The product_of_two_numbers() method is not really returning anything back, to be used elsewhere. Have a look at some of the built-in Python functions, such as max() for example. >>> max(1,2,3) 3 >>> max(1,2,3,4) 4 >>> maximum = max(1,2,3,4) >>> maximum 4 >>> maximum * 5 20 If I call max() with four parameters, as in maximum = max(1,2,3,4), the value 4 gets stored in maximum. Later on in the code that follows, we can say maximum * 5, or we can print the value of maximum, or a similar calculation. This gives our programs a lot more flexibility. So instead of just printing a*b, if this function could return a value, that would be quite useful. >>> def product_of_two_numbers(a,b): ... product = a * b; ... return product ... >>> product_of_two_numbers(2,3) 6 We are creating a variable product and doing a return product. Lets run product_result = product_of_two_numbers(2, 3) >>> product_result = product_of_two_numbers(2,3) >>> product_result 6 >>> product_result * 10 60 You can see how simple it is to return values from a method! Summary In this step, we: Learned how to return values from inside a method Observed how we can store the values returned by a method call Step 10: Programming Exercise PE-MD-02 In this step let's look at a couple of exercises about returning values from methods. Exercises Write a method to return the sum of three integers. Write a method which takes as input two integers, representing two angles of a triangle, and computes the third angle. Hint: The sum of the angles in a triangle is 180 degrees. So if I am passing 50 and 50, 50 plus 50 is 100. So some of three angles should be 180, so the third angle will be 180 - 100, which is 80. Solution 1 >>>def sum_of_three_numbers(a, b, c): ... sum = a + b + c ... return sum ...​ >>> sum_of_three_numbers(1,2,3) 6 >>> something = sum_of_three_numbers(1,2,3) >>> something * 5 30 The shorter way of doing that would have been to have a temporary variable called instead of sum. We could directly return a + b + c. >>> def sum_of_three_numbers(a, b, c): ... return a + b + c ... >>> something = sum_of_three_numbers(1,2,3) >>> something * 5 30 In methods, you can use return expression as well. That expression gets evaluated, and the value gets returned back. You'd see that the result remains the same. Solution 2 The second is to write a method to take two integers, representing two angles of a triangle, and compute the third one. >>> def calculate_third_angle(first, second) : ... return 180 - ( first + second ) ... >>> calculate_third_angle(50, 20) 110 In your programming career, you would be writing a number of methods. It's very important that you are comfortable doing so. Most of the methods that you write would return values back. That's the reason why we're creating a lot of examples involving method calls. Summary In this step, we: Looked at a couple of exercises related to returning values from methods Observed that returning expressions avoids creating unnecessary variables, and shortens method definitions Chapter 04 - Introduction To Python Platform Until now we had been using Python Shell to execute all our code. In the real world, we'll be write Python code in a variety of scripts. Before we would go into an IDE and use the IDE to write the script, we thought it would be useful for us to understand how you can write Python code without the benefit of an IDE. This would also help us understand the Python environment, in-depth. In the next few steps, we'll be looking at how to create simple Python scripts, using any text editor of your choice. Use Notepad, Notepad++. Editpad, or whichever text editing software you are comfortable with. We'll see what involved in executing the program, and what's happening in the background. Here are a few videos you might want to look at.​ Writing and Executing your First Python Script​​ Understanding Python Virtual Machine and bytecode​ Step 01 - Writing and Executing Python Shell Programs Here's a recommended video to watch - Writing and Executing your First Python Script​ Let's get started with creating a simple script file. We want to type in a simple Python script, or a piece of Python code, such as print("Hello world"). Does it get any simpler than this? We'll save this into any folder on our hard disk, with a name 'first.py' . first.py print("Hello world") The '.py' is not really mandatory, but typically all python files end with a '.py' extension. Here's how you can run it: Launch your terminal, or command prompt'cd' to the folder where this python script file is saved execute the command python first.py You will see that Hello World will be printed. If you are familiar with other programming languages, you would need a class, need to put the code in that class, and similar stuff. While Python supports Object Oriented Programming, is not mandatory to create a class. It's almost as if you're typing commands, starting from the line one! That's why we call it a python script. Summary In this small step, we tried to create a simple python script, and we ran it from the command line. All we needed to do, was use the same command we use to launch up the python shell, and followed it up with a name of the file. We created a file called first.py, executed that, and were able to see the output on the console. As an exercise, try and add a few more methods and try to run those methods as well, as part of this script. Step 02 - Python virtual machine and bytecode In this step, let's try and understand what's happening in the background. We wrote a simple piece of code using a text editor. We created a file named first.py, and all we did was: python3 first.py. If you look at other languages like Java for example, there is a separate compilation phase and then an execution phase. But with Python, just this command does both compilation and execution. We saw that, as soon as we make a change and we run python3 first.py , the change is compiled and executed as well! In Python, there is an intermediate format called Python byte code. Code is first compiled to bytecode, and then executed on the Python virtual machine. When we installed Python, we installed both the python compiler and interpreter, as well as the virtual machine. In Python, bytecode is not standardized. Different implementations of Python have different byte code. There are about 80 Python implementations, like CPython and Jython. CPython is a Python implementation in C language. Jython is a Python implementation in Java language. The bytecode which Jython uses is actually Java bytecode, and you can run it on the Java virtual machine. Python leaves a lot of flexibility to the implementations of Python. They have the flexibility to choose the bytecode, and to choose the virtual machine that is compatible. The bytecode is tied to the specific virtual machine you are using. Therefore, if you're using CPython to compile the bytecode, you'll not be able to use Jython to run it. You should make sure, that whatever implementation you are using to compile, is the same one you're using to run the code as well. Summary A lot of this sounds like boring theory. Don't worry about it. As a beginner, this might not be very important for you right now. It's very important for you to understand the process. What's happening is you were writing Python code, and when you ran the command python3 first.py, it is both compiled and executed. An intermediate format called bytecode is created, which is not really standardized in Python. The bytecode is executed in a Python virtual machine. The idea behind this quick section, is to give you a little bit of background on what's happening behind the scenes. I'll see you in the next section. Until then, bye-bye! Chapter 05 - Introduction To VSCode Let's start using the IDE VSCode to write our Python Code Here are recommended videos to watch​ Installing VSCode​​ Write and Execute a Python File with VSCode​​ Write Your First Python Program with VSCode​ Step 01 - Installing and Introduction to VSCode In this quick step, we'll help you install VSCode. Here's the video guide for this step​ Installing VSCode​ Go to Google and type in “VSCode Community Edition Download”. Click the link which comes up first: https://www.jetbrains.com/VSCode/download. You'll go to a page where you can choose the operating system: whether you are on Windows, Mac, or Linux. Once you choose that, you can download the appropriate community version. On the right hand side, you'll see a community version, and you can click the download link, to start the download. If you are having a problem, you can also use the direct link to download. Once you download VSCode, all you need to do is double-click the package which is downloaded. Follow the instructions, and you can continue with the defaults, until you completely install VSCode. When you launch VSCode for the first time, it should ask you for a theme, where you can choose the default. You're all set to go ahead with the next step in the course. VSCode is an awesome IDE, and I'm sure you learn a lot about it. Step 02 - Write and Execute a Python File with VSCode In this step, let's launch up the VSCode IDE, and create our first Python project with a Python script. We want to be able to launch a Python script by the end of this step. Here's the video guide for this step​ Write and Execute a Python File with VSCode​ Launch the VSCode IDE. You'll see that it takes a little while to launch the first time, and then brings up a welcome screen. We would want to create a number of Python files. All these files will be in a project. You can think of our project as a collection of Python scripts, or modules. To get started, let's create a new project by clicking 'create new project'. Let's name it - '01-first-python-project'. Right now there are no files in the project. Let's create our first Python file, using the IDE. The way you can do that is by saying 'right-click' -> 'new' -> 'Python file', and then we'll give this a name of 'hello_world', and click OK. Now you can go ahead and write your first Python program. Let's write some simple code, like print("Hello World"), and save it. You can do a right-click here, and say 'Run hello_world'. A small window comes up below, which shows the output. It says 'Hello World'. Step 03 - Execise - Write Multiplication Table Method with VSCode Let's start with a simple exercise. We created the multiplication table method in the Python Shell. What we do now, is we'll create the same thing but in a Python file of its own. Here's the video guide for this step:​ Write Your First Python Program with VSCode​ Chapter 06 - Introducing Data Types and Conditionals Welcome to this section, where we will talk about numeric data types, and conditional program execution. After looking at the numeric and boolean data types, we will turn our attention to executing code, based on logical conditions. Step 01: Numeric Data Types In previous sections, we created variables of this kind: number = 5 , value = 2.5, etc. The 5 here is an integer, and integers represent numbers, such as 1, 2, 6, -1 and -2. In Python, the class for this particular data type is int. If you write code like type(5), you'd get 'int' as the output. In Python, there are no primitive types. What does that mean? Every value that you see in a Python program, is an object, an instance of some class. In later sections, We'll understand what is a class, and what is an object or an instance. For now, the most important thing for you to remember, is that behind every value, there is a class. Snippet-01: Let's look at 2.5, which is a floating point value. If you go ahead and do type(2.5), what would you see? You would see it's of type ` float. >>> type(2.5) <class 'float'> >>> type(2.55) <class 'float'> When you perform a division operation between two integers, there is a chance that the result of the operation is a float. If you do 5/2, the result is 2.5. If we were to do 4/2, even then it's of type float. >>> type(5/2) <class 'float'> >>> type(4/2) <class 'float'> >>> 4/2 2.0 >>> 1 + 2 3 All the operations we looked at until now, can also be performed on floating point values. >>> value1 = 4.5 >>> value2 = 3.2 >>> value1 + value2 7.7 >>> value1 - value2 1.2999999999999998 >>> value1 / value2 1.40625 >>> value1 % value2 1.2999999999999998 value1 - value2 returns 1.299999999999998. Why? Floating point numbers don't really represent accurate values. That's one of the things you need to always keep in mind. Typically, if you're doing any highly sensitive financial calculations, don't use float s to represent your values. Instead, use Decimal. More about it later. Operations can also be performed between int and float. >>> i + value1 14.5 >>> i - value1 5.5 >>> i / value1 2.2222222222222223 >>> Result of an operation between a int and a float, is always a float. Summary In this step, we: Looked at the two basic numeric types: int and float. Saw the basic operations you can do among int s, among float s, and also between int s and float s. Step 02: Programming Exercise PE-DT-01 In this step, let's do a simple exercise with numeric values. Exercises You need to create a method called simple_interest, and pass three parameters: principal, interest and duration (in years). You also want to calculate the amount after the specific duration, and return it back. Call this method with a few example values. For example, if you want to call simple_interest with 10000, with an interest of 5 percent, for a duration of 5 years, the correct answer would be as follows: 10000 is the principal. In addition to 10000, you get the interest. The interest for one year is 10000 * 0.05, as the interest figure is in percentage.So that's 500 a year, into 5 which is 2500. The result would be 12500, and this value should be printed. Solution 1 def calculate_simple_interest(principal, interest, duration) : return principal * (1 + interest * 0.01 * duration)​ print(calculate_simple_interest(10000,5,5)) Summary In this step, we: Wrote a very simple method to do a simple interest calculation Step 03: Puzzles On Numeric Types In this section, we are looking at numeric types. In this specific step, we would be looking at a few puzzles related to values of these types. Snippet-01: Let's create a simple variable i = 1. i = i + 1. What would be the value of i after that? >>> i = 1 >>> i = i + 1 >>> i 2 It would be 2. There is a shortcut way of doing the same thing, by using the += operator. >>> i += 1 >>> i 3 Typically in other programming languages, you can do something of this kind: i++. There is no provision in Python to use increment operators like ++, in either prefix or suffix mode, like ++i, or i++. >>> i++ File "<stdin>", line 1 i++ ^ SyntaxError: invalid syntax >>> ++i 3 Let's look at compound assignments. >>> i += 1 >>> i 4 >>> i -= 1 >>> i 3 >>> i /= 1 >>> i *= 2 >>> i 6.0 What you see here, is Dynamic Typing in Python. The type of a variable can change during the lifetime of the program.>>> i = 2>>> type(i)<type 'int'>>>> i = i/2.0>>> type(i)<type 'float'> Let's create a couple more numbers. number1 = 5 and number2 = 2. What could be the result of number1 / number2? You know it, it's 2.5 . number1 // nummber2 truncates the value of 2.5, to 2. >>> number1//number2 2 If you can do number1 // number2, can you also do this: number1 //= number2? >>> number1 //= 2 >>> number1 2 5 ** 3 is 5 'to the power of' 3, which is 5 * 5 * 5, or 125. >>> 5 ** 3 125 >>> pow(5,3) 125 This can also be achieved by invoking pow(5, 3). We have an operator, as well as a method at our disposal. The last thing we will look at, are type conversion functions. If you need to convert an int value to a float, or a float to an int. >>> int(5.6) 5 What if you want to round a value? 5.6 is nearer to 6 than 5. You can use a function called round(), and here, round(5.6) gives the correct result 6. >>> round(5.6) 6 >>> round(5.4) 5 >>> round(5.5) 6 round() can also allows you to specify number of decimals in the result. >>> round(5.67, 1) 5.7 >>> round(5.678, 2) 5.68 You can also convert int to float, by using the function float(). >>> float(5) 5.0 Summary In this step, we: Looked at a few corner cases related to your numeric types.
    https://bgoonz-blog.netlify.app/images/code.png
  • My Sites
    My Sites Links Wikipedia Viewer/ /intro-js2.html /
    https://bgoonz-blog.netlify.app/images/code.png
  • Mini Projects Articles
    Close Menu Mini Projects See the Pen searchblog2.0 by Bryan C Guner (@bgoonz) on CodePen. See the Pen Fibonacci Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen Fibonacci Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen embed-twitter-feed by Bryan C Guner (@bgoonz) on CodePen. src="//jsfiddle.net/bgoonz/1dye9uws/2/embedded/js,html,css,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"> See the Pen 3D Cover Flow in React! | @keyframers 3.7 by Bryan C Guner (@bgoonz42) on CodePen. See the Pen Simple Typing Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen 3D Cover Flow in React! | @keyframers 3.7 by Bryan C Guner (@bgoonz42) on CodePen. See the Pen Video Background 1 by Bryan C Guner (@bgoonz) on CodePen. See the Pen CSS-only Colorful Calendar Concept by Bryan C Guner (@bgoonz) on CodePen. See the Pen FullTextSearchjs by Bryan C Guner (@bgoonz) on CodePen. See the Pen CSS Grid: Info Card by Bryan C Guner (@bgoonz42) on CodePen. See the Pen CSS-only Colorful Calendar Concept by Bryan C Guner (@bgoonz) on CodePen. See the Pen Dashed Border Generator by Bryan C Guner (@bgoonz) on CodePen. See the Pen Particle tornado by Bryan C Guner (@bgoonz) on CodePen. See the Pen A Simple Fade Effect on Scroll by Bryan C Guner (@bgoonz) on CodePen. See the Pen Controlled Text Example by Bryan C Guner (@bgoonz) on CodePen. See the Pen MatrixCode by Bryan C Guner (@bgoonz) on CodePen. See the Pen TroisJS InstancedMesh Test by Bryan C Guner (@bgoonz) on CodePen. See the Pen What's behind ? by Bryan C Guner (@bgoonz) on CodePen. See the Pen VectorSwarm by Bryan C Guner (@bgoonz) on CodePen. See the Pen Canvas Sparkly Circle Loader by Bryan C Guner (@bgoonz) on CodePen. See the Pen Canvas particles by Bryan C Guner (@bgoonz) on CodePen. See the Pen Inline Styles with React by Bryan C Guner (@bgoonz) on CodePen. See the Pen Constellation by Bryan C Guner (@bgoonz) on CodePen. See the Pen 95 000 particles by Bryan C Guner (@bgoonz) on CodePen. See the Pen Simple Responsive Form by Bryan Guner (@bgoonz) on CodePen. See the Pen Smooth Page Scrolling in jQuery by Bryan C Guner (@bgoonz) on CodePen. See the Pen Demo Flexbox 3 by Bryan C Guner (@bgoonz) on CodePen. See the Pen Scroll Drawing by Bryan C Guner (@bgoonz) on CodePen. See the Pen Light Javascript Table Filter by Bryan C Guner (@bgoonz) on CodePen. See the Pen CSS Grid: Excel Spreadsheet by Bryan C Guner (@bgoonz) on CodePen. See the Pen 3D Drag out menu with guitar by Bryan C Guner (@bgoonz) on CodePen. See the Pen Navigation bar with circle flexible highlight POC by Bryan C Guner (@bgoonz) on CodePen. See the Pen gsuiOscilloscope by Bryan C Guner (@bgoonz) on CodePen. See the Pen random quote(React.js) by Bryan C Guner (@bgoonz) on CodePen. See the Pen Web Audio API: Lightning Talk by Bryan C Guner (@bgoonz) on CodePen. Back to top
    https://bgoonz-blog.netlify.app/images/beige-maple.png
  • List Of Projects Articles
    List Of Projects WEB DEV RESOURCE HUB Learn Redux Data Structures Website Web-Dev-Quizzes Recursion React Documentation Site Blogs-from-webdevhub Realty Website Demo Best-Prac & Tools site-analysis a/AOpen Notes Iframe Embed Playground Triggered Effects Guitar Platform Live Form Interview Questions Resources Compilation React Blog Depreciated MihirBeg.com Embeded Html Projects Cheat Sheets Early Version Of WebDevHub My Gists DS-Algo-Links Video Chat App Ciriculumn Cheat Sheets Links Medium Articles NextJS Blog Template React Demo Ecomerce Norwex V1 Gifs Excel2HTML Data Structures Site Portfolio Page Templates Photo Gallary Coffee Website Awesome Resources Cheat Sheets Link City VSCODE Extensions webdevhub manual attempt Norwex Resources idk heroku bare bones template bad reads docusaurus stackbit More: https://determined-dijkstra-ee7390 https://bgoonz-blog https://github.com/stackbit-projects/best-celery-b2d7c https://sanity-gatsby-blog-3-web-dnkdb4p7 https://github.com/bgoonz/sanity-gatsby-blog3 https://ds-algo-official https://github.com/bgoonz/DS-ALGO-OFFICIAL https://bgoonz-blog-v3-0 https://github.com/bgoonz/alternate-blog-theme https://sanity-signup https://github.com/bgoonz/successful-cabbage https://bgoonz-bookmarks https://github.com/side-projects-42/superb-celery https://side-bar-blog-4 https://github.com/bgoonz/cool-hickory https://bicknborty https://github.com/bgoonz/searching-bick-n-borty-api https://blog3-backup-dd7df https://github.com/bgoonz/blog3-backup https://bgoonzmedium https://github.com/bgoonz/My-Medium-Blog https://adoring-nobel-85c068 https://github.com/bgoonz/ntn-boilerplate https://random-static-html-deploys https://github.com/bgoonz/random-static-html-page-deploy https://docs42 https://github.com/bgoonz/docs-collection https://bgoonzblog20starter https://github.com/bgoonz/graceful-pine https://marvelous-aluminum-11a84 https://github.com/bgoonz/marvelous-aluminum https://memes42069 https://github.com/stackbit-projects/oceanic-pluto-4029d https://dev-journal42 https://github.com/bgoonz/smart-artichoke https://bg-portfolio https://github.com/bgoonz/gatsby-starter-portfolio-cara https://sanity-gatsby-portfolio-3-studio-bit6zuzq https://github.com/bgoonz/sanity-gatsby-portfolio3 https://sanity-gatsby-portfolio-3-web-4dmiq19t https://random-embedable-content https://github.com/bgoonz/random-list-of-embedable-content https://optimistic-curie-ddd352 https://github.com/bgoonz/yellowcake-mailchimp https://links4242 https://github.com/bgoonz/Links-Shortcut-Site https://zen-bhabha-bd046f https://github.com/bgoonz/Common-npm-Readme-Compilation https://potluck-landing https://github.com/bgoonz/terrific-dolphin https://mihirbegmusiclab https://github.com/bgoonz/MihirBegMusicLab https://interesting-aspen-ce986 https://github.com/bgoonz/interesting-aspen https://mihirbeg28 https://github.com/bgoonz/panoramic-eggplant https://enthusiastic-tomato-a7ebc https://hugo-cms-42 https://github.com/bgoonz/hugo-cms https://bgoonz-cv https://github.com/bgoonz/curious-eggplant https://exploring-next-sanity https://github.com/bgoonz/nervous-parsley https://adoring-carson-fac9fb https://github.com/bgoonz/commercejs-nextjs-demo-store https://kguner-fractions-website https://github.com/Web-Dev-Collaborative/fractions-visualizations-n-resources https://quirky-meninsky-4181b5 https://github.com/side-projects-42/DS-Bash-Examples-Deploy https://starter-520d2 https://github.com/bgoonz/starter https://bg-resume https://github.com/bgoonz/html-resume https://portfolio42 https://github.com/bgoonz/bgoonz.github.io https://objective-rosalind-d4ff71 https://github.com/bgoonz/blog-research https://hungry-shaw-30d504 https://wonderful-pasteur-392fbe https://github.com/bgoonz/norwex-react https://romantic-hamilton-514b79 https://github.com/bgoonz/Cumulative-Resource-List https://stupefied-wilson-2bc726 https://github.com/bgoonz/react-web-anki-flash-cards https://upbeat-mayer-92c10b https://github.com/bgoonz/ecommerce-react https://modest-booth-4e17df https://github.com/bgoonz/Medium_Articles https://blog-v42-31eba https://github.com/bgoonz/blog-v42 https://goofy-curran-95aa66 https://github.com/bgoonz/gatsby-netlify-cms https://react-blog-1 https://github.com/bgoonz/React-Practice https://mihirbegmusic https://github.com/bgoonz/Mihir Beg Final https://bgoonz-games https://github.com/bgoonz/Games https://py-prac-42 https://github.com/bgoonz/PYTHON_PRAC https://synth-music-theory https://github.com/bgoonz/Music-Theory-n-Web-Synth-Keyboard https://admiring-montalcini-965c0b https://github.com/bgoonz/Standalone-Metranome https://sanity-gatsby-blog-3-studio-ch48ysi1 https://github.com/bgoonz/sanity-gatsby-blog3 https://jovial-agnesi-8ec8b1 https://github.com/bgoonz/mini-project-showcase https://ternary42 https://github.com/bgoonz/Ternary-converter https://fourm-builder-gui https://github.com/bgoonz/form-builder-vanilla-js https://lambda-prep https://github.com/bgoonz/lambda-prep https://sanity-kitchen-sink-5-studio-9hogian6 https://ds-unit-5-lambda https://hopeful-shockley-150bee https://github.com/bgoonz/Potluck-Planner https://sidebar-blog https://github.com/side-projects-42/friendly-panda https://cheatsheets42 https://silly-lichterman-b22b5f https://learning-redux42 https://project-portfolio42 https://github.com/bgoonz/curious-zebra https://splendid-onion-b0ec3 https://github.com/stackbit-projects/splendid-onion-b0ec3 https://bgoonzblog20-redo https://github.com/bgoonz/modern-triceratops https://hardcore-hamilton-c5b45e https://github.com/my-lambda-projects/peer https://curious-rabbit-f33af https://github.com/stackbit-projects/curious-rabbit-f33af https://kind-petunia-e8f9f https://github.com/bgoonz/kind-petunia https://elite-cabbage-3551b https://github.com/bgoonz/elite-cabbage https://norwex-next-js https://github.com/bgoonz/commercejs-nextjs-demo-store https://sanity-gatsby-portfolio-studio-89chyji1 https://github.com/bgoonz/sanity-gatsby-portfolio https://sanity-gatsby-blog-studio-m195df5o https://github.com/bgoonz/sanity-gatsby-blog https://sanity-translation-examples-studio-u93wc5ox https://github.com/bgoonz/sanity-translation-examples https://sanity-catalyst-studio-njajg3jt https://github.com/bgoonz/sanity-catalyst https://sanity-catalyst-web-1zjgvx2t https://sanity-nuxt-events-studio-zd46wiji https://github.com/bgoonz/sanity-nuxt-events https://sad-ramanujan-235384 https://gitlab.com/bryan.guner.dev/starter-hugo-online-course https://vibrant-noether-dbe366 https://github.com/bgoonz/jamstack-comments-engine https://objective-torvalds-1c12dd https://github.com/bgoonz/jamstack-comments-engine1 https://friendly-poincare-a11e2f https://github.com/bgoonz/jamstack-comments-engine2 https://sanity-gatsby-blog-4-studio-p6qrh84r https://github.com/bgoonz/sanity-gatsby-blog4 https://festive-kilby-f0a784 https://gitlab.com/bryan.guner.dev/one-click-hugo-cms https://keen-williams-48be7c https://gitlab.com/bryan.guner.dev/algo-prac https://bgoonzgist https://resourcerepo2 https://sanity-gatsby-blog-4-web-mobyn8k4 https://github.com/bgoonz/sanity-gatsby-blog4 https://festive-elion-13b19c https://github.com/bgoonz/nextjs-netlify-blog-template2 https://sanity-nuxt-events-web-i78cd7mw https://github.com/bgoonz/sanity-nuxt-events https://sanity-gatsby-blog-web-skwx3b17 https://github.com/bgoonz/sanity-gatsby-blog https://sanity-gatsby-portfolio-web-1wwhtk8k https://github.com/bgoonz/sanity-gatsby-portfolio https://sanity-gatsby-hey-sugar-5 https://github.com/bgoonz/sanity-gatsby-hey-sugar5 https://unruffled-bhabha-2ea500 https://github.com/bgoonz/commercejs-nextjs-demo-store42 https://bgoonzblog20-backup https://github.com/bgoonz/BGOONZBLOG2.0STABLE https://wizardly-hermann-c9ade8 https://github.com/bgoonz/nextjs-netlify-blog-template https://sanity-kitchen-sink-5-web https://github.com/bgoonz/sanity-kitchen-sink5 https://iframeshowcase https://github.com/bgoonz/iframe-showcase https://friendly-amaranth-51833 https://github.com/bgoonz/friendly-amaranth https://sanity-kitchen-sink-web-geaa75ie https://github.com/bgoonz/sanity-kitchen-sink https://lambda-resources https://github.com/bgoonz/Lambda https://bgoonzblog30 https://github.com/bgoonz/bgoonzblog3.0 https://sanity-commercelayer-web-56265s29 https://github.com/bgoonz/sanity-commercelayer https://sanity-kitchen-sink-studio-us5ymc5z https://github.com/bgoonz/sanity-kitchen-sink https://sanity-commercelayer-1-studio-rkmntw55 https://github.com/bgoonz/sanity-commercelayer1 https://sanity-commercelayer-1-web https://sanity-gatsby-hey-sugar-studio-rkg94h5e https://github.com/bgoonz/sanity-gatsby-hey-sugar https://sanity-gatsby-hey-sugar-web-666eqtdv https://sanity-gatsby-hey-sugar-2-web https://github.com/bgoonz/sanity-gatsby-hey-sugar2 https://sanity-gatsby-hey-sugar-2-studio-1dm9vw5o https://sanity-kitchen-sink-2-studio-71rv9mea https://github.com/bgoonz/sanity-kitchen-sink2 https://sanity-kitchen-sink-2-web-p1dc8gro https://sanity-jigsaw-blog-studio-mgk1nds9 https://github.com/bgoonz/sanity-jigsaw-blog https://sanity-jigsaw-blog-web-cy6y69s7 https://sanity-kitchen-sink-3-studio-qpaz93e3 https://github.com/bgoonz/sanity-kitchen-sink3 https://sanity-kitchen-sink-3-web-v2fb8vmv https://sanity-gatsby-hey-sugar-5-studio https://github.com/bgoonz/sanity-gatsby-hey-sugar5 https://nervous-swartz-0ab2cc https://github.com/bgoonz/ecommerce-interactive https://recursion-prompts https://github.com/bgoonz/Live-htmlRendered-Mocha-Spec--Recursion-Practice https://clever-ramanujan-f9ce0a https://github.com/bgoonz/Lambda-Resource-Static-Assets https://gracious-raman-474030 https://github.com/bgoonz/Data-Struc-Static https://pedantic-wing-adbf82 https://github.com/bgoonz/excel2html-table https://happy-mestorf-0f8e75 https://github.com/bgoonz/zumzi-chat-messenger https://live-form https://github.com/bgoonz/live-form https://trusting-aryabhata-e5438d https://github.com/bgoonz/vscode-Extension-readmes https://jovial-keller-063835 https://github.com/bgoonz/https __mihirbeg.com https://web-dev-resource-hub https://github.com/bgoonz/web-dev-notes-backup https://flamboyant-northcutt-14b025 https://github.com/bgoonz/week-10-take-2 https://bgoonzconnekt4 https://github.com/bgoonz/Connect-Four-Final-Version https://thealgorithms https://hardcore-lamport-7eb855 https://github.com/bgoonz/nextjs-netlify-blog-template42 https://sanity-commercelayer-studio-nzbh7yx7 https://python-playground42 https://github.com/bgoonz/python-playground-embed https://elegant-goodall-566182 https://python-playground43 https://scopeclosurecontext https://github.com/bgoonz/scope-closure-context https://meditate42app https://github.com/bgoonz/meditation-app https://site-analysis https://github.com/bgoonz/site-analysis https://tetris42 https://github.com/bgoonz/TetrisJS https://githtmlpreview https://github.com/bgoonz/GIT-HTML-PREVIEW-TOOL https://devtools42 https://github.com/bgoonz/TexTools https://project-showcase-bgoonz https://github.com/bgoonz/Project-Showcase https://code-playground https://github.com/bgoonz/embedable-repl-and-integrated-code-space-playground https://condescending-lewin-c96727 https://github.com/bgoonz/Revamped-Automatic-Guitar-Effect-Triggering https://oval-cabbage-354f6 https://github.com/bgoonz/oval-cabbage https://web-dev-interview-prep-quiz-website https://github.com/bgoonz/web-dev-interview-prep-quiz-website https://priceless-shaw-86ccb2 https://github.com/bgoonz/atlassian-templates
    https://bgoonz-blog.netlify.app/images/beige-maple.png
  • Gatsby Plugins For This Sites Content Model
    Embeded Websites & Projects Family Promise Project: Table of contents Home navigation NAVIGATION Calendar Youtube: Roadmap: TEAM MEMBERS Running List Of Notes Links & Pertinent Info From Meetings Trello Github/Trello Integration UX UX_TOPICS Action Items: Accessibility Figma Notes Notes Prototyping In Figma More Notes UX-Design Facebook Graph API Ant Design ANT Components Buttons ANT DOCS Application (Codesandbox) Examples How to add external URL links to your prototype CANVAS Design What's Inclusive Design? Accessibility What are Design Systems? Canvas Notes User Experience Design User Research Interaction Design UX-Engineer Patterns Design Tools Design Critiques Product Review Quiz Seven Principles of Design Front End Frontend: Redux Back End Backend: API Research Research Navigation Front End Back End UX PTM General DS_API Data Science API ROLES TEAM ROLES Bryan Guner Action Items Trello Maps ARCHITECTURE DNS AWS Heroku Questions From Previous Cohort Standup Notes Meeting Notes Stakeholder Meeting 1 9/29/2021 GitHub & Project Practice GitHub Github Guide Github Actions: MISC MISCELLANEOUS Background Information Background Info Swagger OPEN API SPECIFICATION GITHUB: Git Bash Git Prune: DOCS Coding Environment Variables Git Rebase: Git Workflow: Linting and Formatting Project Docs Eng-Docs-Home Basic Node API Contributing to this scaffold project Examples: PROJECT DESCRIPTION (Feature List) Labs Learners Guide REACT Create React App Awesome React Links Labs Engineering Docs Okta Basics Roadmap Repositories Workflow Workflow Advice AWS AWS Elastic Beanstalk Elastic Beanstalk DNS Amplify: Amplify-DNS Account Basics AWS-Networking Career & Job Hunt Career Group 1 Live Implementation Family-Promise Application Speach Recognition api Paste To Markdown Paste Excel Tabel To Markdown Paste excel to HTML Cloud Storage Up to 1TB of cloud Storage for file sharing! Resource Archive Lambda Student Site Text Tools Ternary Converter Github HTML Render from link Data Structures Interview Form Builder GUI Border Builder See the Pen Simple Typing Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen Fibonacci Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen embed-twitter-feed by Bryan C Guner (@bgoonz) on CodePen. src="//jsfiddle.net/bgoonz/1dye9uws/2/embedded/js,html,css,result/dark/" allowfullscreen="allowfullscreen" frameborder="0"> See the Pen 3D Cover Flow in React! | @keyframers 3.7 by Bryan C Guner (@bgoonz42) on CodePen. See the Pen Simple Typing Carousel by Bryan C Guner (@bgoonz) on CodePen. See the Pen 3D Cover Flow in React! | @keyframers 3.7 by Bryan C Guner (@bgoonz42) on CodePen. See the Pen Video Background 1 by Bryan C Guner (@bgoonz) on CodePen. See the Pen CSS-only Colorful Calendar Concept by Bryan C Guner (@bgoonz) on CodePen. See the Pen FullTextSearchjs by Bryan C Guner (@bgoonz) on CodePen. See the Pen CSS Grid: Info Card by Bryan C Guner (@bgoonz42) on CodePen. See the Pen CSS-only Colorful Calendar Concept by Bryan C Guner (@bgoonz) on CodePen.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    WhatisTHIS What is THIS If the function is defined as an arrow function: const arrowFunction = () => { console.log(this);}; In this case, the value of this is always the same as this in the parent scope: const outerThis = this;const arrowFunction = () => { // Always logs `true`: console.log(this === outerThis);}; Arrow functions are great because the inner value of this can't be changed, it's always the same as the outer this. Other examples With arrow functions, the value of this can't be changed with bind:// Logs `true` - bound `this` value is ignored:arrowFunction.bind({foo: 'bar'})(); With arrow functions, the value of this can't be changed with call or apply:// Logs `true` - called `this` value is ignored:arrowFunction.call({foo: 'bar'});// Logs `true` - applied `this` value is ignored:arrowFunction.apply({foo: 'bar'}); With arrow functions, the value of this can't be changed by calling the function as a member of another object: const obj = {arrowFunction};// Logs `true` - parent object is ignored:obj.arrowFunction(); With arrow functions, the value of this can't be changed by calling the function as a constructor:// TypeError: arrowFunction is not a constructornew arrowFunction(); 'Bound' instance methods With instance methods, if you want to ensure this always refers to the class instance, the best way is to use arrow functions and class fields: class Whatever { someMethod = () => { // Always the instance of Whatever: console.log(this); };} This pattern is really useful when using instance methods as event listeners in components (such as React components, or web components). The above might feel like it's breaking the " this will be the same as this in the parent scope" rule, but it starts to make sense if you think of class fields as syntactic sugar for setting things in the constructor: class Whatever { someMethod = (() => { const outerThis = this; return () => { // Always logs `true`: console.log(this === outerThis); }; })();}// ...is roughly equivalent to:class Whatever { constructor() { const outerThis = this; this.someMethod = () => { // Always logs `true`: console.log(this === outerThis); }; }} Alternative pattens involve binding an existing function in the constructor, or assigning the function in the constructor. If you can't use class fields for some reason, assigning functions in the constructor is a reasonable alternative: class Whatever { constructor() { this.someMethod = () => { // ... }; }} Otherwise, if the function/class is called with : # new Whatever(); The above will call Whatever (or its constructor function if it's a class) with this set to the result of Object.create(Whatever.prototype). class MyClass { constructor() { console.log( this.constructor === Object.create(MyClass.prototype).constructor, ); }}// Logs `true`:new MyClass(); The same is true for older-style constructors: function MyClass() { console.log( this.constructor === Object.create(MyClass.prototype).constructor, );}// Logs `true`:new MyClass(); Other examples When called with new, the value of this can't be changed with bind: const BoundMyClass = MyClass.bind({foo: 'bar'});// Logs `true` - bound `this` value is ignored:new BoundMyClass(); When called with new, the value of this can't be changed by calling the function as a member of another object: const obj = {MyClass};// Logs `true` - parent object is ignored:new obj.MyClass(); Otherwise, if the function has a 'bound' value: # function someFunction() { return this;}const boundObject = {hello: 'world'};const boundFunction = someFunction.bind(boundObject); Whenever boundFunction is called, its this value will be the object passed to bind ( boundObject).// Logs `false`:console.log(someFunction() === boundObject);// Logs `true`:console.log(boundFunction() === boundObject); Warning: Avoid using bind to bind a function to its outer this. Instead, use arrow functions, as they make this clear from the function declaration, rather than something that happens later in the code. Don't use bind to set this to some value unrelated to the parent object; it's usually unexpected and it's why this gets such a bad reputation. Consider passing the value as an argument instead; it's more explicit, and works with arrow functions. Other examples When calling a bound function, the value of this can't be changed with call or apply:// Logs `true` - called `this` value is ignored:console.log(boundFunction.call({foo: 'bar'}) === boundObject);// Logs `true` - applied `this` value is ignored:console.log(boundFunction.apply({foo: 'bar'}) === boundObject); When calling a bound function, the value of this can't be changed by calling the function as a member of another object: const obj = {boundFunction};// Logs `true` - parent object is ignored:console.log(obj.boundFunction() === boundObject); Otherwise, if is set at call-time: # function someFunction() { return this;}const someObject = {hello: 'world'};// Logs `true`:console.log(someFunction.call(someObject) === someObject);// Logs `true`:console.log(someFunction.apply(someObject) === someObject); The value of this is the object passed to call/ apply. Warning: Don't use call/ apply to set this to some value unrelated to the parent object; it's usually unexpected and it's why this gets such a bad reputation. Consider passing the value as an argument instead; it's more explicit, and works with arrow functions. Unfortunately this is set to some other value by things like DOM event listeners, and using it can result in difficult-to-understand code: Don't element.addEventListener('click', function (event) { // Logs `element`, since the DOM spec sets `this` to // the element the handler is attached to. console.log(this);}); I avoid using this in cases like above, and instead: Do element.addEventListener('click', (event) => { // Ideally, grab it from a parent scope: console.log(element); // But if you can't do that, get it from the event object: console.log(event.currentTarget);}); Otherwise, if the function is called via a parent object (): # const obj = { someMethod() { return this; },};// Logs `true`:console.log(obj.someMethod() === obj); In this case the function is called as a member of obj, so this will be obj. This happens at call-time, so the link is broken if the function is called without its parent object, or with a different parent object: const {someMethod} = obj;// Logs `false`:console.log(someMethod() === obj);const anotherObj = {someMethod};// Logs `false`:console.log(anotherObj.someMethod() === obj);// Logs `true`:console.log(anotherObj.someMethod() === anotherObj); someMethod() === obj is false because someMethod isn't called as a member of obj. You might have encountered this gotcha when trying something like this: const $ = document.querySelector;// TypeError: Illegal invocationconst el = $('.some-element'); This breaks because the implementation of querySelector looks at its own this value and expects it to be a DOM node of sorts, and the above breaks that connection. To achieve the above correctly: const $ = document.querySelector.bind(document);// Or:const $ = (...args) => document.querySelector(...args); Fun fact: Not all APIs use this internally. Console methods like console.log were changed to avoid this references, so log doesn't need to be bound to console. Warning: Don't transplant a function onto an object just to set this to some value unrelated to the parent object; it's usually unexpected and it's why this gets such a bad reputation. Consider passing the value as an argument instead; it's more explicit, and works with arrow functions. Otherwise, if the function or parent scope is in strict mode: function someFunction() { 'use strict'; return this;}// Logs `true`:console.log(someFunction() === undefined); In this case, the value of this is undefined. 'use strict' isn't needed in the function if the parent scope is in strict mode (and all modules are in strict mode). Warning: Don't rely on this. I mean, there are easier ways to get an undefined value 😀. Otherwise: function someFunction() { return this;}// Logs `true`:console.log(someFunction() === globalThis); In this case, the value of this is the same as globalThis.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Javascript Concepts Review Core Concept Review Core Concepts index This appendix is a non-exhaustive list of new syntactic features and methods that were added to JavaScript in ES6. These features are the most commonly used and most helpful. While this appendix doesn't cover ES6 classes, we go over the basics while learning about components in the book. In addition, this appendix doesn't include descriptions of some larger new features like promises and generators. If you'd like more info on those or on any topic below, we encourage you to reference the Mozilla Developer Network's website (MDN). Prefer const and let over var If you've worked with ES5 JavaScript before, you're likely used to seeing variables declared with var: ar myVariable = 5; Both the const and let statements also declare variables. They were introduced in ES6. Use const in cases where a variable is never re-assigned. Using const makes this clear to whoever is reading your code. It refers to the "constant" state of the variable in the context it is defined within. If the variable will be re-assigned, use let. We encourage the use of const and let instead of var. In addition to the restriction introduced by const, both const and let are block scoped as opposed to function scoped. This scoping can help avoid unexpected bugs. Arrow functions There are three ways to write arrow function bodies. For the examples below, let's say we have an array of city objects: onst cities = [ { name: 'Cairo', pop: 7764700 }, { name: 'Lagos', pop: 8029200 }, ]; If we write an arrow function that spans multiple lines, we must use braces to delimit the function body like this: const formattedPopulations = cities.map((city) => { const popMM = (city.pop / 1000000).toFixed(2); return popMM + ' million'; }); console.log(formattedPopulations); Note that we must also explicitly specify a return for the function. However, if we write a function body that is only a single line (or single expression) we can use parentheses to delimit it: const formattedPopulations2 = cities.map((city) => (city.pop / 1000000).toFixed(2) + ' million'); Notably, we don't use return as it's implied. Furthermore, if your function body is terse you can write it like so: const pops = cities.map((city) => city.pop); console.log(pops); The terseness of arrow functions is one of two reasons that we use them. Compare the one-liner above to this: const popsNoArrow = cities.map(function (city) { return city.pop; }); Of greater benefit, though, is how arrow functions bind the this object. The traditional JavaScript function declaration syntax ( function () {}) will bind this in anonymous functions to the global object. To illustrate the confusion this causes, consider the following example: unction printSong() { console.log("Oops - The Global Object"); } const jukebox = { songs: [ { title: "Wanna Be Startin' Somethin'", artist: "Michael Jackson", }, { title: "Superstar", artist: "Madonna", }, ], printSong: function (song) { console.log(song.title + " - " + song.artist); }, printSongs: function () { this.songs.forEach(function(song) { this.printSong(song); }); }, } jukebox.printSongs(); The method printSongs() iterates over this.songs with forEach(). In this context, this is bound to the object ( jukebox) as expected. However, the anonymous function passed to forEach() binds its internal this to the global object. As such, this.printSong(song) calls the function declared at the top of the example, not the method on jukebox. JavaScript developers have traditionally used workarounds for this behavior, but arrow functions solve the problem by capturing the this value of the enclosing context. Using an arrow function for printSongs() has the expected result: printSongs: function () { this.songs.forEach((song) => { this.printSong(song); }); }, } jukebox.printSongs(); For this reason, throughout the book we use arrow functions for all anonymous functions. Modules ES6 formally supports modules using the import/ export syntax. Named exports Inside any file, you can use export to specify a variable the module should expose. Here's an example of a file that exports two functions: export const sayHi = () => console.log('Hi!'); export const sayBye = () => console.log('Bye!'); const saySomething = () => console.log('Something!'); Now, anywhere we wanted to use these functions we could use import. We need to specify which functions we want to import. A common way of doing this is using ES6's destructuring assignment syntax to list them out like this: import { sayHi, sayBye } from './greetings'; sayHi(); sayBye(); Importantly, the function that was not exported ( saySomething) is unavailable outside of the module. Also note that we supply a relative path to from, indicating that the ES6 module is a local file as opposed to an npm package. Instead of inserting an export before each variable you'd like to export, you can use this syntax to list off all the exposed variables in one area: const sayHi = () => console.log('Hi!'); const sayBye = () => console.log('Bye!'); const saySomething = () => console.log('Something!'); export { sayHi, sayBye }; We can also specify that we'd like to import all of a module's functionality underneath a given namespace with the import * as <Namespace> syntax: import * as Greetings from './greetings'; Greetings.sayHi(); Greetings.sayBye(); Greetings.saySomething(); Default export The other type of export is a default export. A module can only contain one default export: const sayHi = () => console.log('Hi!'); const sayBye = () => console.log('Bye!'); const saySomething = () => console.log('Something!'); const Greetings = { sayHi, sayBye }; export default Greetings; This is a common pattern for libraries. It means you can easily import the library wholesale without specifying what individual functions you want: import Greetings from './greetings'; Greetings.sayHi(); Greetings.sayBye(); It's not uncommon for a module to use a mix of both named exports and default exports. For instance, with react-dom, you can import ReactDOM (a default export) like this: import ReactDOM from 'react-dom'; ReactDOM.render(); Or, if you're only going to use the render() function, you can import the named render() function like this: import { render } from 'react-dom'; render(); To achieve this flexibility, the export implementation for react-dom looks something like this: export const render = (component, target) => {}; const ReactDOM = { render }; export default ReactDOM; If you want to play around with the module syntax, check out the folder code/webpack/es6-modules. For more reading on ES6 modules, see this article from Mozilla: " ES6 in Depth: Modules". Object.assign() We use Object.assign() often throughout the book. We use it in areas where we want to create a modified version of an existing object. Object.assign() accepts any number of objects as arguments. When the function receives two arguments, it copies the properties of the second object onto the first, like so: onst coffee = { }; const noCream = { cream: false }; const noMilk = { milk: false }; Object.assign(coffee, noCream); It is idiomatic to pass in three arguments to Object.assign(). The first argument is a new JavaScript object, the one that Object.assign() will ultimately return. The second is the object whose properties we'd like to build off of. The last is the changes we'd like to apply: const coffeeWithMilk = Object.assign({}, coffee, { milk: true }); Object.assign() is a handy method for working with "immutable" JavaScript objects. Template literals In ES5 JavaScript, you'd interpolate variables into strings like this: var greeting = 'Hello, ' + user + '! It is ' + degF + ' degrees outside.'; With ES6 template literals, we can create the same string like this: const greeting = `Hello, ${user}! It is ${degF} degrees outside.`; The spread operator (...) In arrays, the ellipsis ... operator will expand the array that follows into the parent array. The spread operator enables us to succinctly construct new arrays as a composite of existing arrays. Here is an example: onst a = [ 1, 2, 3 ]; const b = [ 4, 5, 6 ]; const c = [ ...a, ...b, 7, 8, 9 ]; console.log(c); Notice how this is different than if we wrote: const d = [a, b, 7, 8, 9]; console.log(d); Enhanced object literals In ES5, all objects were required to have explicit key and value declarations: const explicit = { getState: getState, dispatch: dispatch }; In ES6, you can use this terser syntax whenever the property name and variable name are the same: const implicit = { getState, dispatch }; Lots of open source libraries use this syntax, so it's good to be familiar with it. But whether you use it in your own code is a matter of stylistic preference. Default arguments With ES6, you can specify a default value for an argument in the case that it is undefined when the function is called. This: unction divide(a, b) { const divisor = typeof b === 'undefined' ? 1 : b; return a / divisor; } Can be written as this: function divide(a, b = 1) { return a / b; } In both cases, using the function looks like this: divide(14, 2); divide(14, undefined); divide(14); Whenever the argument b in the example above is undefined, the default argument is used. Note that null will not use the default argument: divide(14, null); Destructuring assignments For arrays In ES5, extracting and assigning multiple elements from an array looked like this: ar fruits = [ 'apples', 'bananas', 'oranges' ]; var fruit1 = fruits[0]; var fruit2 = fruits[1]; In ES6, we can use the destructuring syntax to accomplish the same task like this: const [veg1, veg2] = ['asparagus', 'broccoli', 'onion']; console.log(veg1); console.log(veg2); The variables in the array on the left are "matched" and assigned to the corresponding elements in the array on the right. Note that 'onion' is ignored and has no variable bound to it. For objects We can do something similar for extracting object properties into variables: const smoothie = { fats: ['avocado', 'peanut butter', 'greek yogurt'], liquids: ['almond milk'], greens: ['spinach'], fruits: ['blueberry', 'banana'] }; const { liquids, fruits } = smoothie; console.log(liquids); console.log(fruits); Parameter context matching We can use these same principles to bind arguments inside a function to properties of an object supplied as an argument: const containsSpinach = ({ greens }) => { if (greens.find((g) => g === 'spinach')) { return true; } else { return false; } }; containsSpinach(smoothie); We do this often with functional React components: const IngredientList = ({ ingredients, onClick }) => ( <ul className="IngredientList"> {ingredients.map((i) => ( <li key={i.id} onClick={() => onClick(i.id)} className="item"> {i.name} </li> ))} </ul> ); Here, we use destructuring to extract the props into variables ( ingredients and onClick) that we then use inside the component's function body. Share To Linkedin:
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Promises Promises JavaScript is single threaded, meaning that two bits of script cannot run at the same time; they have to run one after another. In browsers, JavaScript shares a thread with a load of other stuff that differs from browser to browser. But typically JavaScript is in the same queue as painting, updating styles, and handling user actions (such as highlighting text and interacting with form controls). Activity in one of these things delays the others. As a human being, you're multithreaded. You can type with multiple fingers, you can drive and hold a conversation at the same time. The only blocking function we have to deal with is sneezing, where all current activity must be suspended for the duration of the sneeze. That's pretty annoying, especially when you're driving and trying to hold a conversation. You don't want to write code that's sneezy. You've probably used events and callbacks to get around this. Here are events: var img1 = document.querySelector('.img-1');img1.addEventListener('load', function() { // woo yey image loaded});img1.addEventListener('error', function() { // argh everything's broken}); This isn't sneezy at all. We get the image, add a couple of listeners, then JavaScript can stop executing until one of those listeners is called. Unfortunately, in the example above, it's possible that the events happened before we started listening for them, so we need to work around that using the "complete" property of images: var img1 = document.querySelector('.img-1');function loaded() { // woo yey image loaded}if (img1.complete) { loaded();}else { img1.addEventListener('load', loaded);}img1.addEventListener('error', function() { // argh everything's broken}); This doesn't catch images that errored before we got a chance to listen for them; unfortunately the DOM doesn't give us a way to do that. Also, this is loading one image. Things get even more complex if we want to know when a set of images have loaded. Events aren't always the best way Events are great for things that can happen multiple times on the same object--- keyup, touchstart etc. With those events you don't really care about what happened before you attached the listener. But when it comes to async success/failure, ideally you want something like this: img1.callThisIfLoadedOrWhenLoaded(function() { // loaded}).orIfFailedCallThis(function() { // failed});// and...whenAllTheseHaveLoaded([img1, img2]).callThis(function() { // all loaded}).orIfSomeFailedCallThis(function() { // one or more failed}); This is what promises do, but with better naming. If HTML image elements had a "ready" method that returned a promise, we could do this: img1.ready().then(function() { // loaded}, function() { // failed});// and...Promise.all([img1.ready(), img2.ready()]).then(function() { // all loaded}, function() { // one or more failed}); At their most basic, promises are a bit like event listeners except: A promise can only succeed or fail once. It cannot succeed or fail twice, neither can it switch from success to failure or vice versa. If a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called, even though the event took place earlier. This is extremely useful for async success/failure, because you're less interested in the exact time something became available, and more interested in reacting to the outcome. Promise terminology Domenic Denicola proof read the first draft of this article and graded me "F" for terminology. He put me in detention, forced me to copy out States and Fates 100 times, and wrote a worried letter to my parents. Despite that, I still get a lot of the terminology mixed up, but here are the basics: A promise can be: fulfilled - The action relating to the promise succeeded rejected - The action relating to the promise failed pending - Hasn't fulfilled or rejected yet settled - Has fulfilled or rejected The spec also uses the term thenable to describe an object that is promise-like, in that it has a then method. This term reminds me of ex-England Football Manager Terry Venables so I'll be using it as little as possible. Promises arrive in JavaScript! Promises have been around for a while in the form of libraries, such as: Q when WinJS RSVP.js The above and JavaScript promises share a common, standardized behaviour called Promises/A+. If you're a jQuery user, they have something similar called Deferreds. However, Deferreds aren't Promise/A+ compliant, which makes them subtly different and less useful, so beware. jQuery also has a Promise type, but this is just a subset of Deferred and has the same issues. Although promise implementations follow a standardized behaviour, their overall APIs differ. JavaScript promises are similar in API to RSVP.js. Here's how you create a promise: var promise = new Promise(function(resolve, reject) { // do a thing, possibly async, then... if (/* everything turned out fine */) { resolve("Stuff worked!"); } else { reject(Error("It broke")); }}); The promise constructor takes one argument, a callback with two parameters, resolve and reject. Do something within the callback, perhaps async, then call resolve if everything worked, otherwise call reject. Like throw in plain old JavaScript, it's customary, but not required, to reject with an Error object. The benefit of Error objects is they capture a stack trace, making debugging tools more helpful. Here's how you use that promise: promise.then(function(result) { console.log(result); // "Stuff worked!"}, function(err) { console.log(err); // Error: "It broke"}); then() takes two arguments, a callback for a success case, and another for the failure case. Both are optional, so you can add a callback for the success or failure case only. JavaScript promises started out in the DOM as "Futures", renamed to "Promises", and finally moved into JavaScript. Having them in JavaScript rather than the DOM is great because they'll be available in non-browser JS contexts such as Node.js (whether they make use of them in their core APIs is another question). Although they're a JavaScript feature, the DOM isn't afraid to use them. In fact, all new DOM APIs with async success/failure methods will use promises. This is happening already with Quota Management, Font Load Events, ServiceWorker, Web MIDI, Streams, and more. Browser support & polyfill There are already implementations of promises in browsers today. As of Chrome 32, Opera 19, Firefox 29, Safari 8 & Microsoft Edge, promises are enabled by default. To bring browsers that lack a complete promises implementation up to spec compliance, or add promises to other browsers and Node.js, check out the polyfill (2k gzipped). Compatibility with other libraries The JavaScript promises API will treat anything with a then() method as promise-like (or thenable in promise-speak sigh), so if you use a library that returns a Q promise, that's fine, it'll play nice with the new JavaScript promises. Although, as I mentioned, jQuery's Deferreds are a bit ... unhelpful. Thankfully you can cast them to standard promises, which is worth doing as soon as possible: var jsPromise = Promise.resolve($.ajax('/whatever.json')) Here, jQuery's $.ajax returns a Deferred. Since it has a then() method, Promise.resolve() can turn it into a JavaScript promise. However, sometimes deferreds pass multiple arguments to their callbacks, for example: var jqDeferred = $.ajax('/whatever.json');jqDeferred.then(function(response, statusText, xhrObj) { // ...}, function(xhrObj, textStatus, err) { // ...}) Whereas JS promises ignore all but the first: jsPromise.then(function(response) { // ...}, function(xhrObj) { // ...}) Thankfully this is usually what you want, or at least gives you access to what you want. Also, be aware that jQuery doesn't follow the convention of passing Error objects into rejections. Complex async code made easier Right, let's code some things. Say we want to: Start a spinner to indicate loading Fetch some JSON for a story, which gives us the title, and urls for each chapter Add title to the page Fetch each chapter Add the story to the page Stop the spinner... but also tell the user if something went wrong along the way. We'll want to stop the spinner at that point too, else it'll keep on spinning, get dizzy, and crash into some other UI. Of course, you wouldn't use JavaScript to deliver a story, serving as HTML is faster, but this pattern is pretty common when dealing with APIs: Multiple data fetches, then do something when it's all done. To start with, let's deal with fetching data from the network: Promisifying XMLHttpRequest Old APIs will be updated to use promises, if it's possible in a backwards compatible way. XMLHttpRequest is a prime candidate, but in the mean time let's write a simple function to make a GET request: function get(url) { // Return a new promise. return new Promise(function(resolve, reject) { // Do the usual XHR stuff var req = new XMLHttpRequest(); req.open('GET', url); req.onload = function() { // This is called even on 404 etc // so check the status if (req.status == 200) { // Resolve the promise with the response text resolve(req.response); } else { // Otherwise reject with the status text // which will hopefully be a meaningful error reject(Error(req.statusText)); } }; // Handle network errors req.onerror = function() { reject(Error("Network Error")); }; // Make the request req.send(); });} Now let's use it: get('story.json').then(function(response) { console.log("Success!", response);}, function(error) { console.error("Failed!", error);}) Now we can make HTTP requests without manually typing XMLHttpRequest, which is great, because the less I have to see the infuriating camel-casing of XMLHttpRequest, the happier my life will be. Chaining then() isn't the end of the story, you can chain then s together to transform values or run additional async actions one after another. Transforming values You can transform values simply by returning the new value: var promise = new Promise(function(resolve, reject) { resolve(1);});promise.then(function(val) { console.log(val); // 1 return val + 2;}).then(function(val) { console.log(val); // 3}) As a practical example, let's go back to: get('story.json').then(function(response) { console.log("Success!", response);}) The response is JSON, but we're currently receiving it as plain text. We could alter our get function to use the JSON responseType, but we could also solve it in promises land: get('story.json').then(function(response) { return JSON.parse(response);}).then(function(response) { console.log("Yey JSON!", response);}) Since JSON.parse() takes a single argument and returns a transformed value, we can make a shortcut: get('story.json').then(JSON.parse).then(function(response) { console.log("Yey JSON!", response);}) In fact, we could make a getJSON() function really easily: function getJSON(url) { return get(url).then(JSON.parse);} getJSON() still returns a promise, one that fetches a url then parses the response as JSON. Queuing asynchronous actions You can also chain then s to run async actions in sequence. When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails). For example: getJSON('story.json').then(function(story) { return getJSON(story.chapterUrls[0]);}).then(function(chapter1) { console.log("Got chapter 1!", chapter1);}) Here we make an async request to story.json, which gives us a set of URLs to request, then we request the first of those. This is when promises really start to stand out from simple callback patterns. You could even make a shortcut method to get chapters: var storyPromise;function getChapter(i) { storyPromise = storyPromise || getJSON('story.json'); return storyPromise.then(function(story) { return getJSON(story.chapterUrls[i]); })}// and using it is simple:getChapter(0).then(function(chapter) { console.log(chapter); return getChapter(1);}).then(function(chapter) { console.log(chapter);}) We don't download story.json until getChapter is called, but the next time(s) getChapter is called we reuse the story promise, so story.json is only fetched once. Yay Promises! Error handling As we saw earlier, then() takes two arguments, one for success, one for failure (or fulfill and reject, in promises-speak): get('story.json').then(function(response) { console.log("Success!", response);}, function(error) { console.log("Failed!", error);}) You can also use catch(): get('story.json').then(function(response) { console.log("Success!", response);}).catch(function(error) { console.log("Failed!", error);}) There's nothing special about catch(), it's just sugar for then(undefined, func), but it's more readable. Note that the two code examples above do not behave the same, the latter is equivalent to: get('story.json').then(function(response) { console.log("Success!", response);}).then(undefined, function(error) { console.log("Failed!", error);}) The difference is subtle, but extremely useful. Promise rejections skip forward to the next then() with a rejection callback (or catch(), since it's equivalent). With then(func1, func2), func1 or func2 will be called, never both. But with then(func1).catch(func2), both will be called if func1 rejects, as they're separate steps in the chain. Take the following: asyncThing1().then(function() { return asyncThing2();}).then(function() { return asyncThing3();}).catch(function(err) { return asyncRecovery1();}).then(function() { return asyncThing4();}, function(err) { return asyncRecovery2();}).catch(function(err) { console.log("Don't worry about it");}).then(function() { console.log("All done!");}) The flow above is very similar to normal JavaScript try/catch, errors that happen within a "try" go immediately to the catch() block. Here's the above as a flowchart (because I love flowcharts): Follow the blue lines for promises that fulfill, or the red for ones that reject. JavaScript exceptions and promises Rejections happen when a promise is explicitly rejected, but also implicitly if an error is thrown in the constructor callback: var jsonPromise = new Promise(function(resolve, reject) { // JSON.parse throws an error if you feed it some // invalid JSON, so this implicitly rejects: resolve(JSON.parse("This ain't JSON"));});jsonPromise.then(function(data) { // This never happens: console.log("It worked!", data);}).catch(function(err) { // Instead, this happens: console.log("It failed!", err);}) This means it's useful to do all your promise-related work inside the promise constructor callback, so errors are automatically caught and become rejections. The same goes for errors thrown in then() callbacks. get('/').then(JSON.parse).then(function() { // This never happens, '/' is an HTML page, not JSON // so JSON.parse throws console.log("It worked!", data);}).catch(function(err) { // Instead, this happens: console.log("It failed!", err);}) Error handling in practice With our story and chapters, we can use catch to display an error to the user: getJSON('story.json').then(function(story) { return getJSON(story.chapterUrls[0]);}).then(function(chapter1) { addHtmlToPage(chapter1.html);}).catch(function() { addTextToPage("Failed to show chapter");}).then(function() { document.querySelector('.spinner').style.display = 'none';}) If fetching story.chapterUrls[0] fails (e.g., http 500 or user is offline), it'll skip all following success callbacks, which includes the one in getJSON() which tries to parse the response as JSON, and also skips the callback that adds chapter1.html to the page. Instead it moves onto the catch callback. As a result, "Failed to show chapter" will be added to the page if any of the previous actions failed. Like JavaScript's try/catch, the error is caught and subsequent code continues, so the spinner is always hidden, which is what we want. The above becomes a non-blocking async version of: try { var story = getJSONSync('story.json'); var chapter1 = getJSONSync(story.chapterUrls[0]); addHtmlToPage(chapter1.html);}catch (e) { addTextToPage("Failed to show chapter");}document.querySelector('.spinner').style.display = 'none' You may want to catch() simply for logging purposes, without recovering from the error. To do this, just rethrow the error. We could do this in our getJSON() method: function getJSON(url) { return get(url).then(JSON.parse).catch(function(err) { console.log("getJSON failed for", url, err); throw err; });} So we've managed to fetch one chapter, but we want them all. Let's make that happen. Parallelism and sequencing: getting the best of both Thinking async isn't easy. If you're struggling to get off the mark, try writing the code as if it were synchronous. In this case: try { var story = getJSONSync('story.json'); addHtmlToPage(story.heading); story.chapterUrls.forEach(function(chapterUrl) { var chapter = getJSONSync(chapterUrl); addHtmlToPage(chapter.html); }); addTextToPage("All done");}catch (err) { addTextToPage("Argh, broken: " + err.message);}document.querySelector('.spinner').style.display = 'none' That works! But it's sync and locks up the browser while things download. To make this work async we use then() to make things happen one after another. getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); // TODO: for each url in story.chapterUrls, fetch &amp; display}).then(function() { // And we're all done! addTextToPage("All done");}).catch(function(err) { // Catch any error that happened along the way addTextToPage("Argh, broken: " + err.message);}).then(function() { // Always hide the spinner document.querySelector('.spinner').style.display = 'none';}) But how can we loop through the chapter urls and fetch them in order? This doesn't work: story.chapterUrls.forEach(function(chapterUrl) { // Fetch chapter getJSON(chapterUrl).then(function(chapter) { // and add it to the page addHtmlToPage(chapter.html); });}) forEach isn't async-aware, so our chapters would appear in whatever order they download, which is basically how Pulp Fiction was written. This isn't Pulp Fiction, so let's fix it. Creating a sequence We want to turn our chapterUrls array into a sequence of promises. We can do that using then():// Start off with a promise that always resolvesvar sequence = Promise.resolve();// Loop through our chapter urlsstory.chapterUrls.forEach(function(chapterUrl) { // Add these actions to the end of the sequence sequence = sequence.then(function() { return getJSON(chapterUrl); }).then(function(chapter) { addHtmlToPage(chapter.html); });}) This is the first time we've seen Promise.resolve(), which creates a promise that resolves to whatever value you give it. If you pass it an instance of Promise it'll simply return it (note: this is a change to the spec that some implementations don't yet follow). If you pass it something promise-like (has a then() method), it creates a genuine Promise that fulfills/rejects in the same way. If you pass in any other value, e.g., Promise.resolve('Hello'), it creates a promise that fulfills with that value. If you call it with no value, as above, it fulfills with "undefined". There's also Promise.reject(val), which creates a promise that rejects with the value you give it (or undefined). We can tidy up the above code using array.reduce:// Loop through our chapter urlsstory.chapterUrls.reduce(function(sequence, chapterUrl) { // Add these actions to the end of the sequence return sequence.then(function() { return getJSON(chapterUrl); }).then(function(chapter) { addHtmlToPage(chapter.html); });}, Promise.resolve()) This is doing the same as the previous example, but doesn't need the separate "sequence" variable. Our reduce callback is called for each item in the array. "sequence" is Promise.resolve() the first time around, but for the rest of the calls "sequence" is whatever we returned from the previous call. array.reduce is really useful for boiling an array down to a single value, which in this case is a promise. Let's put it all together: getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); return story.chapterUrls.reduce(function(sequence, chapterUrl) { // Once the last chapter's promise is done... return sequence.then(function() { // ...fetch the next chapter return getJSON(chapterUrl); }).then(function(chapter) { // and add it to the page addHtmlToPage(chapter.html); }); }, Promise.resolve());}).then(function() { // And we're all done! addTextToPage("All done");}).catch(function(err) { // Catch any error that happened along the way addTextToPage("Argh, broken: " + err.message);}).then(function() { // Always hide the spinner document.querySelector('.spinner').style.display = 'none';}) And there we have it, a fully async version of the sync version. But we can do better. At the moment our page is downloading like this: Browsers are pretty good at downloading multiple things at once, so we're losing performance by downloading chapters one after the other. What we want to do is download them all at the same time, then process them when they've all arrived. Thankfully there's an API for this: Promise.all(arrayOfPromises).then(function(arrayOfResults) { //...}) Promise.all takes an array of promises and creates a promise that fulfills when all of them successfully complete. You get an array of results (whatever the promises fulfilled to) in the same order as the promises you passed in. getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); // Take an array of promises and wait on them all return Promise.all( // Map our array of chapter urls to // an array of chapter json promises story.chapterUrls.map(getJSON) );}).then(function(chapters) { // Now we have the chapters jsons in order! Loop through... chapters.forEach(function(chapter) { // ...and add to the page addHtmlToPage(chapter.html); }); addTextToPage("All done");}).catch(function(err) { // catch any error that happened so far addTextToPage("Argh, broken: " + err.message);}).then(function() { document.querySelector('.spinner').style.display = 'none';}) Depending on connection, this can be seconds faster than loading one-by-one, and it's less code than our first try. The chapters can download in whatever order, but they appear on screen in the right order. However, we can still improve perceived performance. When chapter one arrives we should add it to the page. This lets the user start reading before the rest of the chapters have arrived. When chapter three arrives, we wouldn't add it to the page because the user may not realize chapter two is missing. When chapter two arrives, we can add chapters two and three, etc etc. To do this, we fetch JSON for all our chapters at the same time, then create a sequence to add them to the document: getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); // Map our array of chapter urls to // an array of chapter json promises. // This makes sure they all download in parallel. return story.chapterUrls.map(getJSON) .reduce(function(sequence, chapterPromise) { // Use reduce to chain the promises together, // adding content to the page for each chapter return sequence .then(function() { // Wait for everything in the sequence so far, // then wait for this chapter to arrive. return chapterPromise; }).then(function(chapter) { addHtmlToPage(chapter.html); }); }, Promise.resolve());}).then(function() { addTextToPage("All done");}).catch(function(err) { // catch any error that happened along the way addTextToPage("Argh, broken: " + err.message);}).then(function() { document.querySelector('.spinner').style.display = 'none';})
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Constructor Functions Constructor Functions Defining a constructor function Example of an object using object initialiation const fellowshipOfTheRing = { title: 'The Fellowship of the Ring', series: 'The Lord of the Rings', author: 'J.R.R. Tolkien' }; The above literal is a "Book" object type. Object Type is defined by it's attributes and behaviors. Behaviors are represented by methods. Constructor Functions : Handle the creation of an object - it's a factory for creating objects of a specific type. There are a few specific things to constructors worth noting: The name of the constructor function is capitalized The Function does not explicityly return a value Within the body, the this keyword references the newly created object function Book(title, series, author) { this.title = title; this.series = series; this.author = author; } Invoking a constructor function We can invoke a constructor function using the new keyword. function Book(title, series, author) { this.title = title; this.series = series; this.author = author; } const fellowshipOfTheRing = new Book('The Fellowship of the Ring', 'The Lord of the Rings', 'J.R.R. Tolkien'); console.log(fellowshipOfTheRing); // Book { title: 'The Fellowship of the Ring', ... } Four Things will happen when invoking a constructor function A new empty object is created {}; The new obj's prototype is set to the object referenced by the constructors prototype property. This is bound to the new object. The new object is returned after the constructor function has completed. Understanding New Object Instances Instance : term to describe an objected created from a constructor function. Every instance created is a unique object and therefore not equal to each other. Using the instanceof operator to check an object's type console.log(fellowshipOfTheRing instanceof Book); // true By using the instanceof operator we can verify that an object was created from a certain object type. The instanceOf operator works by checking to see if the prototype object of the left side of the operator is the same as the prototype object of the right side of the operator. Invoking a constructor function without the new keyword If we invoke a constructor function without the new keyword, we may result in one of two unexpected outcomes: In non-strict mode, this will be bound to the global object instead. In strict mode, this will become undefined. You can enable strict mode by typing "use strict" at the top of your file. Defining Sharable Methods Avoid the temptation to store an object method inside a constructor function, it is inefficient with computer memory usage b/c each object instance would have it's own method definition. Prototype : An object that is delegated to when a reference to an object property or method can't be resolved. Every instance created by a constructor function shares the same prototype. Object.setPrototypeOf() and Object.getPrototypeOf() are just used to set a prototype of one object to another object; and also the verify a prototype. proto : aka "dunder proto" is a property used to gain easy access to an object's prototype - it is widely supported by browsers but is considered deprecated. function Book(title, series, author) { this.title = title; this.series = series; this.author = author; } // Any method defined on the `Book.prototype` property // will be shared across all `Book` instances. Book.prototype.getInformation = function () { return `${this.title} by ${this.author}`; }; const fellowshipOfTheRing = new Book('The Fellowship of the Ring', 'The Lord of the Rings', 'J.R.R. Tolkien'); console.log(fellowshipOfTheRing.getInformation()); Every method we define on a constructor function's prototype property will be shared across all instances of that object type. The Problem with Arrow Functions We cannot use arrow functions when defining methods on a constructor function's prototype property. Arrow functions don't include their own this binding; therefore it will not reference the current instance - always stick with the function () keyword. Putting the Class in Javascript Classes In ES2015, JS gained the class keyword - replacing the need to use only constructor functions & prototypes to mimic classes! class : keyword that gives developers a formal way to create a class definition to specify an object type's attributes and behavior; also used to create objects of that specific type. Defining a ES2015 class class Book { constructor(title, series, author) { this.title = title; this.series = series; this.author = author; } } Class names also begin only with capital letters. Although not required, class definitions can include a class constructor function - these are similar to regular constructors in that: They don't explicitly return a value. The this keyword references the newly created object instance. Instantiating an instance of a class We can also use the new. Four things occur when instantiating an instance of a class: New empty object is created {}; The new obj's prototype is set to the class prototype's property value. This is bound to the new object. After the constructor method has completed, the new obj is returned. Don't try to instatiate a class object without the new keyword. Class Definitions are NOT hoisted test(); function test() { console.log('This works!'); } In JS you can call a function before it's declared - this is known as hoisting. Class defs are NOT hoisted, so just get in the habit of declaring them before you use them. Defining Methods A class can contain two types of methods: Instance Method : Methods that are invoked on an instance of the class - useful for performing an action on a specific instance. Instance methods are also sometimes referred to as prototype methods because they are defined on a shared prototype object. Static Method : Methods that invoked directly on a class, not on an instance. Important: Invoking a static method on an instance will result in a runtime error. Prepending the static keyword at the beginning on the method name will make it static. class Book { constructor(title, series, author) { this.title = title; this.series = series; this.author = author; } // Notice the use of a rest parameter (...books) // to capture the passed parameters as an array of values. static getTitles(...books) { return books.map((book) => book.title); } getInformation() { return `${this.title} by ${this.author}`; } } const fellowshipOfTheRing = new Book('The Fellowship of the Ring', 'The Lord of the Rings', 'J.R.R. Tolkien'); const theTwoTowers = new Book('The Two Towers', 'The Lord of the Rings', 'J.R.R. Tolkien'); const bookTitles = Book.getTitles(fellowshipOfTheRing, theTwoTowers); console.log(bookTitles.join(', ')); // The Fellowship of the Ring, The Two Towers If we go back to an example of how constructor functions also use static methods - we see that static methods are defined directly on the constructor function - whereas instance methods need to be defined on the prototype object. function Book(title, series, author) { this.title = title; this.series = series; this.author = author; } // Static methods are defined // directly on the constructor function. Book.getTitles = function (...books) { return books.map((book) => book.title); }; // Instance methods are defined // on the constructor function's `prototype` property. Book.prototype.getInformation = function () { return `${this.title} by ${this.author}`; }; const fellowshipOfTheRing = new Book('The Fellowship of the Ring', 'The Lord of the Rings', 'J.R.R. Tolkien'); const theTwoTowers = new Book('The Two Towers', 'The Lord of the Rings', 'J.R.R. Tolkien'); console.log(fellowshipOfTheRing.getInformation()); // The Fellowship of the Ring by J.R.R. Tolkien console.log(theTwoTowers.getInformation()); // The Two Towers by J.R.R. Tolkien // Call the static `Book.getTitles()` method // to get an array of the book titles. const bookTitles = Book.getTitles(fellowshipOfTheRing, theTwoTowers); console.log(bookTitles.join(', ')); // The Fellowship of the Ring, The Two Towers Comparing Classes to Constructor Functions ES2015 Classes are essentially syntactic sugar over traditional constructor functions and prototypes. Javascript Inheritance Child Class : Class that is based upon another class and inherits properties and methods from that other class. Parent Class : Class that is being inherited downwards. Inheritance : The process of basing a class upon another class. class CatalogItem { constructor(title, series) { this.title = title; this.series = series; } getInformation() { if (this.series) { return `${this.title} (${this.series})`; } else { return this.title; } } } class Book extends CatalogItem { constructor(title, series, author) { super(title, series); this.author = author; } } class Movie extends CatalogItem { constructor(title, series, director) { super(title, series); this.director = director; } } const theGrapesOfWrath = new Book('The Grapes of Wrath', null, 'John Steinbeck'); const aNewHope = new Movie('Episode 4: A New Hope', 'Star Wars', 'George Lucas'); console.log(theGrapesOfWrath.getInformation()); // The Grapes of Wrath console.log(aNewHope.getInformation()); // Episode 4: A New Hope (Star Wars) console.log(Catalogitem instanceof Function); // true console.log(Book instanceof Function); // true A prototype chain defines a series of prototype objects that are delegated to one by one, when a property or method can't be found on an instance object. console.log(theGrapesOfWrath.getInformation()); // The Grapes of Wrath When the getInformation() method is invoked: JS looks for get() on the current object. If it isn't found, the method call is delegated to the object's prototype. It continues up the prototype chain until the method is found. Overriding a method in a parent class Method Overriding : when a child class provides an implementation of a method that's already defined in a parent class. class Movie extends CatalogItem { constructor(title, series, director) { super(title, series); this.director = director; } getInformation() { let result = super.getInformation(); if (this.director) { result += ` [directed by ${this.director}]`; } return result; } } We can simply declare our own method of the same name in our child class to override our parent's version of getInformation() Javascript Modules Introducing Node.js modules In Node.js, each JS file in a project defines a module. Module's contents are private by default. Local Modules : Modules defined within your project. Core Modules : Native modules contained within Node.js that you can use to perform tasks or to add functionality to your application. CommonJS : A legacy module system. ES Modules : Newer module sysem that will eventually replace CommonJS. Entry Point : JS File that is passed to Node for access to the entire application. Syntax for exporting modules: module.exports.Book = Book; module.exports.Movie = Movie; module.exports = { Book, Movie }; Syntax for importing modules: const classes = require('./classes'); const { Book, Movie } = require('./classes'); Using Single Item Modules Following the convention of a single exported item per module helps to keep modules focused and less likely to become bloted with too much code. Understanding Module Loading When loading a module, Node will examine the identifier passed to the require() function to determine if our module is local, core, or third-party: Local Module: identifier starts with ./ ../ or / Node.js Core: identifier matches name Third-Party: identifier matches a module in the node modules folder (installed package)
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Clean Code clean-code-javascript Table of Contents Introduction Variables Functions Objects and Data Structures Classes SOLID Testing Concurrency Error Handling Formatting Comments Translation Introduction Software engineering principles, from Robert C. Martin's book Clean Code, adapted for JavaScript. This is not a style guide. It's a guide to producing readable, reusable, and refactorable software in JavaScript. Not every principle herein has to be strictly followed, and even fewer will be universally agreed upon. These are guidelines and nothing more, but they are ones codified over many years of collective experience by the authors of Clean Code. Our craft of software engineering is just a bit over 50 years old, and we are still learning a lot. When software architecture is as old as architecture itself, maybe then we will have harder rules to follow. For now, let these guidelines serve as a touchstone by which to assess the quality of the JavaScript code that you and your team produce. One more thing: knowing these won't immediately make you a better software developer, and working with them for many years doesn't mean you won't make mistakes. Every piece of code starts as a first draft, like wet clay getting shaped into its final form. Finally, we chisel away the imperfections when we review it with our peers. Don't beat yourself up for first drafts that need improvement. Beat up the code instead! Variables Use meaningful and pronounceable variable names Bad: const yyyymmdstr = moment().format('YYYY/MM/DD'); Good: const currentDate = moment().format('YYYY/MM/DD'); Use the same vocabulary for the same type of variable Bad: getUserInfo(); getClientData(); getCustomerRecord(); Good: getUser(); Use searchable names We will read more code than we will ever write. It's important that the code we do write is readable and searchable. By not naming variables that end up being meaningful for understanding our program, we hurt our readers. Make your names searchable. Tools like buddy.js and ESLint can help identify unnamed constants. Bad:// What the heck is 86400000 for? setTimeout(blastOff, 86400000); Good:// Declare them as capitalized named constants. const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000; //86400000; setTimeout(blastOff, MILLISECONDS_PER_DAY); Use explanatory variables Bad: const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; saveCityZipCode(address.match(cityZipCodeRegex)[1], address.match(cityZipCodeRegex)[2]); Good: const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; const [_, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode); Avoid Mental Mapping Explicit is better than implicit. Bad: const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((l) => { doStuff(); doSomeOtherStuff(); // ... // ... // ... // Wait, what is `l` for again? dispatch(l); }); Good: const locations = ['Austin', 'New York', 'San Francisco']; locations.forEach((location) => { doStuff(); doSomeOtherStuff(); // ... // ... // ... dispatch(location); }); Don't add unneeded context If your class/object name tells you something, don't repeat that in your variable name. Bad: const Car = { carMake: 'Honda', carModel: 'Accord', carColor: 'Blue' }; function paintCar(car, color) { car.carColor = color; } Good: const Car = { make: 'Honda', model: 'Accord', color: 'Blue' }; function paintCar(car, color) { car.color = color; } Use default arguments instead of short circuiting or conditionals Default arguments are often cleaner than short circuiting. Be aware that if you use them, your function will only provide default values for undefined arguments. Other "falsy" values such as '', "", false, null, 0, and NaN, will not be replaced by a default value. Bad: function createMicrobrewery(name) { const breweryName = name || 'Hipster Brew Co.'; // ... } Good: function createMicrobrewery(name = 'Hipster Brew Co.') { // ... } Functions Function arguments (2 or fewer ideally) Limiting the amount of function parameters is incredibly important because it makes testing your function easier. Having more than three leads to a combinatorial explosion where you have to test tons of different cases with each separate argument. One or two arguments is the ideal case, and three should be avoided if possible. Anything more than that should be consolidated. Usually, if you have more than two arguments then your function is trying to do too much. In cases where it's not, most of the time a higher-level object will suffice as an argument. Since JavaScript allows you to make objects on the fly, without a lot of class boilerplate, you can use an object if you are finding yourself needing a lot of arguments. To make it obvious what properties the function expects, you can use the ES2015/ES6 destructuring syntax. This has a few advantages: When someone looks at the function signature, it's immediately clear what properties are being used. It can be used to simulate named parameters. Destructuring also clones the specified primitive values of the argument object passed into the function. This can help prevent side effects. Note: objects and arrays that are destructured from the argument object are NOT cloned. Linters can warn you about unused properties, which would be impossible without destructuring. Bad: function createMenu(title, body, buttonText, cancellable) { // ... } createMenu('Foo', 'Bar', 'Baz', true); Good: function createMenu({ title, body, buttonText, cancellable }) { // ... } createMenu({ title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true }); Functions should do one thing This is by far the most important rule in software engineering. When functions do more than one thing, they are harder to compose, test, and reason about. When you can isolate a function to just one action, it can be refactored easily and your code will read much cleaner. If you take nothing else away from this guide other than this, you'll be ahead of many developers. Bad: function emailClients(clients) { clients.forEach((client) => { const clientRecord = database.lookup(client); if (clientRecord.isActive()) { email(client); } }); } Good: function emailActiveClients(clients) { clients.filter(isActiveClient).forEach(email); } function isActiveClient(client) { const clientRecord = database.lookup(client); return clientRecord.isActive(); } Function names should say what they do Bad: function addToDate(date, month) { // ... } const date = new Date(); // It's hard to tell from the function name what is added addToDate(date, 1); Good: function addMonthToDate(month, date) { // ... } const date = new Date(); addMonthToDate(1, date); Functions should only be one level of abstraction When you have more than one level of abstraction your function is usually doing too much. Splitting up functions leads to reusability and easier testing. Bad: function parseBetterJSAlternative(code) { const REGEXES = [ // ... ]; const statements = code.split(' '); const tokens = []; REGEXES.forEach((REGEX) => { statements.forEach((statement) => { // ... }); }); const ast = []; tokens.forEach((token) => { // lex... }); ast.forEach((node) => { // parse... }); } Good: function parseBetterJSAlternative(code) { const tokens = tokenize(code); const syntaxTree = parse(tokens); syntaxTree.forEach((node) => { // parse... }); } function tokenize(code) { const REGEXES = [ // ... ]; const statements = code.split(' '); const tokens = []; REGEXES.forEach((REGEX) => { statements.forEach((statement) => { tokens.push(/* ... */); }); }); return tokens; } function parse(tokens) { const syntaxTree = []; tokens.forEach((token) => { syntaxTree.push(/* ... */); }); return syntaxTree; } Remove duplicate code Do your absolute best to avoid duplicate code. Duplicate code is bad because it means that there's more than one place to alter something if you need to change some logic. Imagine if you run a restaurant and you keep track of your inventory: all your tomatoes, onions, garlic, spices, etc. If you have multiple lists that you keep this on, then all have to be updated when you serve a dish with tomatoes in them. If you only have one list, there's only one place to update! Oftentimes you have duplicate code because you have two or more slightly different things, that share a lot in common, but their differences force you to have two or more separate functions that do much of the same things. Removing duplicate code means creating an abstraction that can handle this set of different things with just one function/module/class. Getting the abstraction right is critical, that's why you should follow the SOLID principles laid out in the Classes section. Bad abstractions can be worse than duplicate code, so be careful! Having said this, if you can make a good abstraction, do it! Don't repeat yourself, otherwise you'll find yourself updating multiple places anytime you want to change one thing. Bad: function showDeveloperList(developers) { developers.forEach((developer) => { const expectedSalary = developer.calculateExpectedSalary(); const experience = developer.getExperience(); const githubLink = developer.getGithubLink(); const data = { expectedSalary, experience, githubLink }; render(data); }); } function showManagerList(managers) { managers.forEach((manager) => { const expectedSalary = manager.calculateExpectedSalary(); const experience = manager.getExperience(); const portfolio = manager.getMBAProjects(); const data = { expectedSalary, experience, portfolio }; render(data); }); } Good: function showEmployeeList(employees) { employees.forEach((employee) => { const expectedSalary = employee.calculateExpectedSalary(); const experience = employee.getExperience(); const data = { expectedSalary, experience }; switch (employee.type) { case 'manager': data.portfolio = employee.getMBAProjects(); break; case 'developer': data.githubLink = employee.getGithubLink(); break; } render(data); }); } Set default objects with Object.assign Bad: const menuConfig = { title: null, body: 'Bar', buttonText: null, cancellable: true }; function createMenu(config) { config.title = config.title || 'Foo'; config.body = config.body || 'Bar'; config.buttonText = config.buttonText || 'Baz'; config.cancellable = config.cancellable !== undefined ? config.cancellable : true; } createMenu(menuConfig); Good: const menuConfig = { title: 'Order', // User did not include 'body' key buttonText: 'Send', cancellable: true }; function createMenu(config) { let finalConfig = Object.assign( { title: 'Foo', body: 'Bar', buttonText: 'Baz', cancellable: true }, config ); return finalConfig; // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true} // ... } createMenu(menuConfig); Don't use flags as function parameters Flags tell your user that this function does more than one thing. Functions should do one thing. Split out your functions if they are following different code paths based on a boolean. Bad: function createFile(name, temp) { if (temp) { fs.create(`./temp/${name}`); } else { fs.create(name); } } Good: function createFile(name) { fs.create(name); } function createTempFile(name) { createFile(`./temp/${name}`); } Avoid Side Effects (part 1) A function produces a side effect if it does anything other than take a value in and return another value or values. A side effect could be writing to a file, modifying some global variable, or accidentally wiring all your money to a stranger. Now, you do need to have side effects in a program on occasion. Like the previous example, you might need to write to a file. What you want to do is to centralize where you are doing this. Don't have several functions and classes that write to a particular file. Have one service that does it. One and only one. The main point is to avoid common pitfalls like sharing state between objects without any structure, using mutable data types that can be written to by anything, and not centralizing where your side effects occur. If you can do this, you will be happier than the vast majority of other programmers. Bad:// Global variable referenced by following function. // If we had another function that used this name, now it'd be an array and it could break it. let name = 'Ryan McDermott'; function splitIntoFirstAndLastName() { name = name.split(' '); } splitIntoFirstAndLastName(); console.log(name); // ['Ryan', 'McDermott']; Good: function splitIntoFirstAndLastName(name) { return name.split(' '); } const name = 'Ryan McDermott'; const newName = splitIntoFirstAndLastName(name); console.log(name); // 'Ryan McDermott'; console.log(newName); // ['Ryan', 'McDermott']; Avoid Side Effects (part 2) In JavaScript, some values are unchangeable (immutable) and some are changeable (mutable). Objects and arrays are two kinds of mutable values so it's important to handle them carefully when they're passed as parameters to a function. A JavaScript function can change an object's properties or alter the contents of an array which could easily cause bugs elsewhere. Suppose there's a function that accepts an array parameter representing a shopping cart. If the function makes a change in that shopping cart array - by adding an item to purchase, for example - then any other function that uses that same cart array will be affected by this addition. That may be great, however it could also be bad. Let's imagine a bad situation: The user clicks the "Purchase" button which calls a purchase function that spawns a network request and sends the cart array to the server. Because of a bad network connection, the purchase function has to keep retrying the request. Now, what if in the meantime the user accidentally clicks an "Add to Cart" button on an item they don't actually want before the network request begins? If that happens and the network request begins, then that purchase function will send the accidentally added item because the cart array was modified. A great solution would be for the addItemToCart function to always clone the cart, edit it, and return the clone. This would ensure that functions that are still using the old shopping cart wouldn't be affected by the changes. Two caveats to mention to this approach: There might be cases where you actually want to modify the input object, but when you adopt this programming practice you will find that those cases are pretty rare. Most things can be refactored to have no side effects! Cloning big objects can be very expensive in terms of performance. Luckily, this isn't a big issue in practice because there are great libraries that allow this kind of programming approach to be fast and not as memory intensive as it would be for you to manually clone objects and arrays. Bad: const addItemToCart = (cart, item) => { cart.push({ item, date: Date.now() }); }; Good: const addItemToCart = (cart, item) => { return [...cart, { item, date: Date.now() }]; }; Don't write to global functions Polluting globals is a bad practice in JavaScript because you could clash with another library and the user of your API would be none-the-wiser until they get an exception in production. Let's think about an example: what if you wanted to extend JavaScript's native Array method to have a diff method that could show the difference between two arrays? You could write your new function to the Array.prototype, but it could clash with another library that tried to do the same thing. What if that other library was just using diff to find the difference between the first and last elements of an array? This is why it would be much better to just use ES2015/ES6 classes and simply extend the Array global. Bad: Array.prototype.diff = function diff(comparisonArray) { const hash = new Set(comparisonArray); return this.filter((elem) => !hash.has(elem)); }; Good: class SuperArray extends Array { diff(comparisonArray) { const hash = new Set(comparisonArray); return this.filter((elem) => !hash.has(elem)); } } Favor functional programming over imperative programming JavaScript isn't a functional language in the way that Haskell is, but it has a functional flavor to it. Functional languages can be cleaner and easier to test. Favor this style of programming when you can. Bad: const programmerOutput = [ { name: 'Uncle Bobby', linesOfCode: 500 }, { name: 'Suzie Q', linesOfCode: 1500 }, { name: 'Jimmy Gosling', linesOfCode: 150 }, { name: 'Gracie Hopper', linesOfCode: 1000 } ]; let totalOutput = 0; for (let i = 0; i < programmerOutput.length; i++) { totalOutput += programmerOutput[i].linesOfCode; } Good: const programmerOutput = [ { name: 'Uncle Bobby', linesOfCode: 500 }, { name: 'Suzie Q', linesOfCode: 1500 }, { name: 'Jimmy Gosling', linesOfCode: 150 }, { name: 'Gracie Hopper', linesOfCode: 1000 } ]; const totalOutput = programmerOutput.reduce((totalLines, output) => totalLines + output.linesOfCode, 0); Encapsulate conditionals Bad: if (fsm.state === 'fetching' && isEmpty(listNode)) { // ... } Good: function shouldShowSpinner(fsm, listNode) { return fsm.state === 'fetching' && isEmpty(listNode); } if (shouldShowSpinner(fsmInstance, listNodeInstance)) { // ... } Avoid negative conditionals Bad: function isDOMNodeNotPresent(node) { // ... } if (!isDOMNodeNotPresent(node)) { // ... } Good: function isDOMNodePresent(node) { // ... } if (isDOMNodePresent(node)) { // ... } Avoid conditionals This seems like an impossible task. Upon first hearing this, most people say, "how am I supposed to do anything without an if statement?" The answer is that you can use polymorphism to achieve the same task in many cases. The second question is usually, "well that's great but why would I want to do that?" The answer is a previous clean code concept we learned: a function should only do one thing. When you have classes and functions that have if statements, you are telling your user that your function does more than one thing. Remember, just do one thing. Bad: class Airplane { // ... getCruisingAltitude() { switch (this.type) { case '777': return this.getMaxAltitude() - this.getPassengerCount(); case 'Air Force One': return this.getMaxAltitude(); case 'Cessna': return this.getMaxAltitude() - this.getFuelExpenditure(); } } } Good: class Airplane { // ... } class Boeing777 extends Airplane { // ... getCruisingAltitude() { return this.getMaxAltitude() - this.getPassengerCount(); } } class AirForceOne extends Airplane { // ... getCruisingAltitude() { return this.getMaxAltitude(); } } class Cessna extends Airplane { // ... getCruisingAltitude() { return this.getMaxAltitude() - this.getFuelExpenditure(); } } Avoid type-checking (part 1) JavaScript is untyped, which means your functions can take any type of argument. Sometimes you are bitten by this freedom and it becomes tempting to do type-checking in your functions. There are many ways to avoid having to do this. The first thing to consider is consistent APIs. Bad: function travelToTexas(vehicle) { if (vehicle instanceof Bicycle) { vehicle.pedal(this.currentLocation, new Location('texas')); } else if (vehicle instanceof Car) { vehicle.drive(this.currentLocation, new Location('texas')); } } Good: function travelToTexas(vehicle) { vehicle.move(this.currentLocation, new Location('texas')); } Avoid type-checking (part 2) If you are working with basic primitive values like strings and integers, and you can't use polymorphism but you still feel the need to type-check, you should consider using TypeScript. It is an excellent alternative to normal JavaScript, as it provides you with static typing on top of standard JavaScript syntax. The problem with manually type-checking normal JavaScript is that doing it well requires so much extra verbiage that the faux "type-safety" you get doesn't make up for the lost readability. Keep your JavaScript clean, write good tests, and have good code reviews. Otherwise, do all of that but with TypeScript (which, like I said, is a great alternative!). Bad: function combine(val1, val2) { if ((typeof val1 === 'number' && typeof val2 === 'number') || (typeof val1 === 'string' && typeof val2 === 'string')) { return val1 + val2; } throw new Error('Must be of type String or Number'); } Good: function combine(val1, val2) { return val1 + val2; } Don't over-optimize Modern browsers do a lot of optimization under-the-hood at runtime. A lot of times, if you are optimizing then you are just wasting your time. There are good resources for seeing where optimization is lacking. Target those in the meantime, until they are fixed if they can be. Bad:// On old browsers, each iteration with uncached `list.length` would be costly // because of `list.length` recomputation. In modern browsers, this is optimized. for (let i = 0, len = list.length; i < len; i++) { // ... } Good: for (let i = 0; i < list.length; i++) { // ... } Remove dead code Dead code is just as bad as duplicate code. There's no reason to keep it in your codebase. If it's not being called, get rid of it! It will still be safe in your version history if you still need it. Bad: function oldRequestModule(url) { // ... } function newRequestModule(url) { // ... } const req = newRequestModule; inventoryTracker('apples', req, 'www.inventory-awesome.io'); Good: function newRequestModule(url) { // ... } const req = newRequestModule; inventoryTracker('apples', req, 'www.inventory-awesome.io'); Objects and Data Structures Use getters and setters Using getters and setters to access data on objects could be better than simply looking for a property on an object. "Why?" you might ask. Well, here's an unorganized list of reasons why: When you want to do more beyond getting an object property, you don't have to look up and change every accessor in your codebase. Makes adding validation simple when doing a set. Encapsulates the internal representation. Easy to add logging and error handling when getting and setting. You can lazy load your object's properties, let's say getting it from a server. Bad: function makeBankAccount() { // ... return { balance: 0 // ... }; } const account = makeBankAccount(); account.balance = 100; Good: function makeBankAccount() { // this one is private let balance = 0; // a "getter", made public via the returned object below function getBalance() { return balance; } // a "setter", made public via the returned object below function setBalance(amount) { // ... validate before updating the balance balance = amount; } return { // ... getBalance, setBalance }; } const account = makeBankAccount(); account.setBalance(100); Make objects have private members This can be accomplished through closures (for ES5 and below). Bad: const Employee = function (name) { this.name = name; }; Employee.prototype.getName = function getName() { return this.name; }; const employee = new Employee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined Good: function makeEmployee(name) { return { getName() { return name; } }; } const employee = makeEmployee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe Classes Prefer ES2015/ES6 classes over ES5 plain functions It's very difficult to get readable class inheritance, construction, and method definitions for classical ES5 classes. If you need inheritance (and be aware that you might not), then prefer ES2015/ES6 classes. However, prefer small functions over classes until you find yourself needing larger and more complex objects. Bad: const Animal = function (age) { if (!(this instanceof Animal)) { throw new Error('Instantiate Animal with `new`'); } this.age = age; }; Animal.prototype.move = function move() {}; const Mammal = function (age, furColor) { if (!(this instanceof Mammal)) { throw new Error('Instantiate Mammal with `new`'); } Animal.call(this, age); this.furColor = furColor; }; Mammal.prototype = Object.create(Animal.prototype); Mammal.prototype.constructor = Mammal; Mammal.prototype.liveBirth = function liveBirth() {}; const Human = function (age, furColor, languageSpoken) { if (!(this instanceof Human)) { throw new Error('Instantiate Human with `new`'); } Mammal.call(this, age, furColor); this.languageSpoken = languageSpoken; }; Human.prototype = Object.create(Mammal.prototype); Human.prototype.constructor = Human; Human.prototype.speak = function speak() {}; Good: class Animal { constructor(age) { this.age = age; } move() { /* ... */ } } class Mammal extends Animal { constructor(age, furColor) { super(age); this.furColor = furColor; } liveBirth() { /* ... */ } } class Human extends Mammal { constructor(age, furColor, languageSpoken) { super(age, furColor); this.languageSpoken = languageSpoken; } speak() { /* ... */ } } Use method chaining This pattern is very useful in JavaScript and you see it in many libraries such as jQuery and Lodash. It allows your code to be expressive, and less verbose. For that reason, I say, use method chaining and take a look at how clean your code will be. In your class functions, simply return this at the end of every function, and you can chain further class methods onto it. Bad: class Car { constructor(make, model, color) { this.make = make; this.model = model; this.color = color; } setMake(make) { this.make = make; } setModel(model) { this.model = model; } setColor(color) { this.color = color; } save() { console.log(this.make, this.model, this.color); } } const car = new Car('Ford', 'F-150', 'red'); car.setColor('pink'); car.save(); Good: class Car { constructor(make, model, color) { this.make = make; this.model = model; this.color = color; } setMake(make) { this.make = make; // NOTE: Returning this for chaining return this; } setModel(model) { this.model = model; // NOTE: Returning this for chaining return this; } setColor(color) { this.color = color; // NOTE: Returning this for chaining return this; } save() { console.log(this.make, this.model, this.color); // NOTE: Returning this for chaining return this; } } const car = new Car('Ford', 'F-150', 'red').setColor('pink').save(); Prefer composition over inheritance As stated famously in Design Patterns by the Gang of Four, you should prefer composition over inheritance where you can. There are lots of good reasons to use inheritance and lots of good reasons to use composition. The main point for this maxim is that if your mind instinctively goes for inheritance, try to think if composition could model your problem better. In some cases it can. You might be wondering then, "when should I use inheritance?" It depends on your problem at hand, but this is a decent list of when inheritance makes more sense than composition: Your inheritance represents an "is-a" relationship and not a "has-a" relationship (Human->Animal vs. User->UserDetails). You can reuse code from the base classes (Humans can move like all animals). You want to make global changes to derived classes by changing a base class. (Change the caloric expenditure of all animals when they move). Bad: class Employee { constructor(name, email) { this.name = name; this.email = email; } // ... } // Bad because Employees "have" tax data. EmployeeTaxData is not a type of Employee class EmployeeTaxData extends Employee { constructor(ssn, salary) { super(); this.ssn = ssn; this.salary = salary; } // ... } Good: class EmployeeTaxData { constructor(ssn, salary) { this.ssn = ssn; this.salary = salary; } // ... } class Employee { constructor(name, email) { this.name = name; this.email = email; } setTaxData(ssn, salary) { this.taxData = new EmployeeTaxData(ssn, salary); } // ... } SOLID Single Responsibility Principle (SRP) As stated in Clean Code, "There should never be more than one reason for a class to change". It's tempting to jam-pack a class with a lot of functionality, like when you can only take one suitcase on your flight. The issue with this is that your class won't be conceptually cohesive and it will give it many reasons to change. Minimizing the amount of times you need to change a class is important. It's important because if too much functionality is in one class and you modify a piece of it, it can be difficult to understand how that will affect other dependent modules in your codebase. Bad: class UserSettings { constructor(user) { this.user = user; } changeSettings(settings) { if (this.verifyCredentials()) { // ... } } verifyCredentials() { // ... } } Good: class UserAuth { constructor(user) { this.user = user; } verifyCredentials() { // ... } } class UserSettings { constructor(user) { this.user = user; this.auth = new UserAuth(user); } changeSettings(settings) { if (this.auth.verifyCredentials()) { // ... } } } Open/Closed Principle (OCP) As stated by Bertrand Meyer, "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification." What does that mean though? This principle basically states that you should allow users to add new functionalities without changing existing code. Bad: class AjaxAdapter extends Adapter { constructor() { super(); this.name = 'ajaxAdapter'; } } class NodeAdapter extends Adapter { constructor() { super(); this.name = 'nodeAdapter'; } } class HttpRequester { constructor(adapter) { this.adapter = adapter; } fetch(url) { if (this.adapter.name === 'ajaxAdapter') { return makeAjaxCall(url).then((response) => { // transform response and return }); } else if (this.adapter.name === 'nodeAdapter') { return makeHttpCall(url).then((response) => { // transform response and return }); } } } function makeAjaxCall(url) { // request and return promise } function makeHttpCall(url) { // request and return promise } Good: class AjaxAdapter extends Adapter { constructor() { super(); this.name = 'ajaxAdapter'; } request(url) { // request and return promise } } class NodeAdapter extends Adapter { constructor() { super(); this.name = 'nodeAdapter'; } request(url) { // request and return promise } } class HttpRequester { constructor(adapter) { this.adapter = adapter; } fetch(url) { return this.adapter.request(url).then((response) => { // transform response and return }); } } Liskov Substitution Principle (LSP) This is a scary term for a very simple concept. It's formally defined as "If S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.)." That's an even scarier definition. The best explanation for this is if you have a parent class and a child class, then the base class and child class can be used interchangeably without getting incorrect results. This might still be confusing, so let's take a look at the classic Square-Rectangle example. Mathematically, a square is a rectangle, but if you model it using the "is-a" relationship via inheritance, you quickly get into trouble. Bad: class Rectangle { constructor() { this.width = 0; this.height = 0; } setColor(color) { // ... } render(area) { // ... } setWidth(width) { this.width = width; } setHeight(height) { this.height = height; } getArea() { return this.width * this.height; } } class Square extends Rectangle { setWidth(width) { this.width = width; this.height = width; } setHeight(height) { this.width = height; this.height = height; } } function renderLargeRectangles(rectangles) { rectangles.forEach((rectangle) => { rectangle.setWidth(4); rectangle.setHeight(5); const area = rectangle.getArea(); // BAD: Returns 25 for Square. Should be 20. rectangle.render(area); }); } const rectangles = [new Rectangle(), new Rectangle(), new Square()]; renderLargeRectangles(rectangles); Good: class Shape { setColor(color) { // ... } render(area) { // ... } } class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; } getArea() { return this.width * this.height; } } class Square extends Shape { constructor(length) { super(); this.length = length; } getArea() { return this.length * this.length; } } function renderLargeShapes(shapes) { shapes.forEach((shape) => { const area = shape.getArea(); shape.render(area); }); } const shapes = [new Rectangle(4, 5), new Rectangle(4, 5), new Square(5)]; renderLargeShapes(shapes); Interface Segregation Principle (ISP) JavaScript doesn't have interfaces so this principle doesn't apply as strictly as others. However, it's important and relevant even with JavaScript's lack of type system. ISP states that "Clients should not be forced to depend upon interfaces that they do not use." Interfaces are implicit contracts in JavaScript because of duck typing. A good example to look at that demonstrates this principle in JavaScript is for classes that require large settings objects. Not requiring clients to setup huge amounts of options is beneficial, because most of the time they won't need all of the settings. Making them optional helps prevent having a "fat interface". Bad: class DOMTraverser { constructor(settings) { this.settings = settings; this.setup(); } setup() { this.rootNode = this.settings.rootNode; this.settings.animationModule.setup(); } traverse() { // ... } } const $ = new DOMTraverser({ rootNode: document.getElementsByTagName('body'), animationModule() {} // Most of the time, we won't need to animate when traversing. // ... }); Good: class DOMTraverser { constructor(settings) { this.settings = settings; this.options = settings.options; this.setup(); } setup() { this.rootNode = this.settings.rootNode; this.setupOptions(); } setupOptions() { if (this.options.animationModule) { // ... } } traverse() { // ... } } const $ = new DOMTraverser({ rootNode: document.getElementsByTagName('body'), options: { animationModule() {} } }); Dependency Inversion Principle (DIP) This principle states two essential things: High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend upon details. Details should depend on abstractions. This can be hard to understand at first, but if you've worked with AngularJS, you've seen an implementation of this principle in the form of Dependency Injection (DI). While they are not identical concepts, DIP keeps high-level modules from knowing the details of its low-level modules and setting them up. It can accomplish this through DI. A huge benefit of this is that it reduces the coupling between modules. Coupling is a very bad development pattern because it makes your code hard to refactor. As stated previously, JavaScript doesn't have interfaces so the abstractions that are depended upon are implicit contracts. That is to say, the methods and properties that an object/class exposes to another object/class. In the example below, the implicit contract is that any Request module for an InventoryTracker will have a requestItems method. Bad: class InventoryRequester { constructor() { this.REQ_METHODS = ['HTTP']; } requestItem(item) { // ... } } class InventoryTracker { constructor(items) { this.items = items; // BAD: We have created a dependency on a specific request implementation. // We should just have requestItems depend on a request method: `request` this.requester = new InventoryRequester(); } requestItems() { this.items.forEach((item) => { this.requester.requestItem(item); }); } } const inventoryTracker = new InventoryTracker(['apples', 'bananas']); inventoryTracker.requestItems(); Good: class InventoryTracker { constructor(items, requester) { this.items = items; this.requester = requester; } requestItems() { this.items.forEach((item) => { this.requester.requestItem(item); }); } } class InventoryRequesterV1 { constructor() { this.REQ_METHODS = ['HTTP']; } requestItem(item) { // ... } } class InventoryRequesterV2 { constructor() { this.REQ_METHODS = ['WS']; } requestItem(item) { // ... } } // By constructing our dependencies externally and injecting them, we can easily // substitute our request module for a fancy new one that uses WebSockets. const inventoryTracker = new InventoryTracker(['apples', 'bananas'], new InventoryRequesterV2()); inventoryTracker.requestItems(); Testing Testing is more important than shipping. If you have no tests or an inadequate amount, then every time you ship code you won't be sure that you didn't break anything. Deciding on what constitutes an adequate amount is up to your team, but having 100% coverage (all statements and branches) is how you achieve very high confidence and developer peace of mind. This means that in addition to having a great testing framework, you also need to use a good coverage tool. There's no excuse to not write tests. There are plenty of good JS test frameworks, so find one that your team prefers. When you find one that works for your team, then aim to always write tests for every new feature/module you introduce. If your preferred method is Test Driven Development (TDD), that is great, but the main point is to just make sure you are reaching your coverage goals before launching any feature, or refactoring an existing one. Single concept per test Bad: import assert from 'assert'; describe('MomentJS', () => { it('handles date boundaries', () => { let date; date = new MomentJS('1/1/2015'); date.addDays(30); assert.equal('1/31/2015', date); date = new MomentJS('2/1/2016'); date.addDays(28); assert.equal('02/29/2016', date); date = new MomentJS('2/1/2015'); date.addDays(28); assert.equal('03/01/2015', date); }); }); Good: import assert from 'assert'; describe('MomentJS', () => { it('handles 30-day months', () => { const date = new MomentJS('1/1/2015'); date.addDays(30); assert.equal('1/31/2015', date); }); it('handles leap year', () => { const date = new MomentJS('2/1/2016'); date.addDays(28); assert.equal('02/29/2016', date); }); it('handles non-leap year', () => { const date = new MomentJS('2/1/2015'); date.addDays(28); assert.equal('03/01/2015', date); }); }); Concurrency Use Promises, not callbacks Callbacks aren't clean, and they cause excessive amounts of nesting. With ES2015/ES6, Promises are a built-in global type. Use them! Bad: import { get } from 'request'; import { writeFile } from 'fs'; get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', (requestErr, response, body) => { if (requestErr) { console.error(requestErr); } else { writeFile('article.html', body, (writeErr) => { if (writeErr) { console.error(writeErr); } else { console.log('File written'); } }); } }); Good: import { get } from 'request-promise'; import { writeFile } from 'fs-extra'; get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin') .then((body) => { return writeFile('article.html', body); }) .then(() => { console.log('File written'); }) .catch((err) => { console.error(err); }); Async/Await are even cleaner than Promises Promises are a very clean alternative to callbacks, but ES2017/ES8 brings async and await which offer an even cleaner solution. All you need is a function that is prefixed in an async keyword, and then you can write your logic imperatively without a then chain of functions. Use this if you can take advantage of ES2017/ES8 features today! Bad: import { get } from 'request-promise'; import { writeFile } from 'fs-extra'; get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin') .then((body) => { return writeFile('article.html', body); }) .then(() => { console.log('File written'); }) .catch((err) => { console.error(err); }); Good: import { get } from 'request-promise'; import { writeFile } from 'fs-extra'; async function getCleanCodeArticle() { try { const body = await get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin'); await writeFile('article.html', body); console.log('File written'); } catch (err) { console.error(err); } } getCleanCodeArticle(); Error Handling Thrown errors are a good thing! They mean the runtime has successfully identified when something in your program has gone wrong and it's letting you know by stopping function execution on the current stack, killing the process (in Node), and notifying you in the console with a stack trace. Don't ignore caught errors Doing nothing with a caught error doesn't give you the ability to ever fix or react to said error. Logging the error to the console ( console.log) isn't much better as often times it can get lost in a sea of things printed to the console. If you wrap any bit of code in a try/catch it means you think an error may occur there and therefore you should have a plan, or create a code path, for when it occurs. Bad: try { functionThatMightThrow(); } catch (error) { console.log(error); } Good: try { functionThatMightThrow(); } catch (error) { // One option (more noisy than console.log): console.error(error); // Another option: notifyUserOfError(error); // Another option: reportErrorToService(error); // OR do all three! } Don't ignore rejected promises For the same reason you shouldn't ignore caught errors from try/catch. Bad: getdata() .then((data) => { functionThatMightThrow(data); }) .catch((error) => { console.log(error); }); Good: getdata() .then((data) => { functionThatMightThrow(data); }) .catch((error) => { // One option (more noisy than console.log): console.error(error); // Another option: notifyUserOfError(error); // Another option: reportErrorToService(error); // OR do all three! }); Formatting Formatting is subjective. Like many rules herein, there is no hard and fast rule that you must follow. The main point is DO NOT ARGUE over formatting. There are tons of tools to automate this. Use one! It's a waste of time and money for engineers to argue over formatting. For things that don't fall under the purview of automatic formatting (indentation, tabs vs. spaces, double vs. single quotes, etc.) look here for some guidance. Use consistent capitalization JavaScript is untyped, so capitalization tells you a lot about your variables, functions, etc. These rules are subjective, so your team can choose whatever they want. The point is, no matter what you all choose, just be consistent. Bad: const DAYS_IN_WEEK = 7; const daysInMonth = 30; const songs = ['Back In Black', 'Stairway to Heaven', 'Hey Jude']; const Artists = ['ACDC', 'Led Zeppelin', 'The Beatles']; function eraseDatabase() {} function restore_database() {} class animal {} class Alpaca {} Good: const DAYS_IN_WEEK = 7; const DAYS_IN_MONTH = 30; const SONGS = ['Back In Black', 'Stairway to Heaven', 'Hey Jude']; const ARTISTS = ['ACDC', 'Led Zeppelin', 'The Beatles']; function eraseDatabase() {} function restoreDatabase() {} class Animal {} class Alpaca {} Function callers and callees should be close If a function calls another, keep those functions vertically close in the source file. Ideally, keep the caller right above the callee. We tend to read code from top-to-bottom, like a newspaper. Because of this, make your code read that way. Bad: class PerformanceReview { constructor(employee) { this.employee = employee; } lookupPeers() { return db.lookup(this.employee, 'peers'); } lookupManager() { return db.lookup(this.employee, 'manager'); } getPeerReviews() { const peers = this.lookupPeers(); // ... } perfReview() { this.getPeerReviews(); this.getManagerReview(); this.getSelfReview(); } getManagerReview() { const manager = this.lookupManager(); } getSelfReview() { // ... } } const review = new PerformanceReview(employee); review.perfReview(); Good: class PerformanceReview { constructor(employee) { this.employee = employee; } perfReview() { this.getPeerReviews(); this.getManagerReview(); this.getSelfReview(); } getPeerReviews() { const peers = this.lookupPeers(); // ... } lookupPeers() { return db.lookup(this.employee, 'peers'); } getManagerReview() { const manager = this.lookupManager(); } lookupManager() { return db.lookup(this.employee, 'manager'); } getSelfReview() { // ... } } const review = new PerformanceReview(employee); review.perfReview(); Comments Only comment things that have business logic complexity. Comments are an apology, not a requirement. Good code mostly documents itself. Bad: function hashIt(data) { // The hash let hash = 0; // Length of string const length = data.length; // Loop through every character in data for (let i = 0; i < length; i++) { // Get character code. const char = data.charCodeAt(i); // Make the hash hash = (hash << 5) - hash + char; // Convert to 32-bit integer hash &= hash; } } Good: function hashIt(data) { let hash = 0; const length = data.length; for (let i = 0; i < length; i++) { const char = data.charCodeAt(i); hash = (hash << 5) - hash + char; // Convert to 32-bit integer hash &= hash; } } Don't leave commented out code in your codebase Version control exists for a reason. Leave old code in your history. Bad: doStuff(); // doOtherStuff(); // doSomeMoreStuff(); // doSoMuchStuff(); Good: doStuff(); Don't have journal comments Remember, use version control! There's no need for dead code, commented code, and especially journal comments. Use git log to get history! Bad:/** * 2016-12-20: Removed monads, didn't understand them (RM) * 2016-10-01: Improved using special monads (JP) * 2016-02-03: Removed type-checking (LI) * 2015-03-14: Added combine with type-checking (JR) */ function combine(a, b) { return a + b; } Good: function combine(a, b) { return a + b; } Avoid positional markers They usually just add noise. Let the functions and variable names along with the proper indentation and formatting give the visual structure to your code. Bad://////////////////////////////////////////////////////////////////////////////// // Scope Model Instantiation //////////////////////////////////////////////////////////////////////////////// $scope.model = { menu: 'foo', nav: 'bar' }; //////////////////////////////////////////////////////////////////////////////// // Action setup //////////////////////////////////////////////////////////////////////////////// const actions = function () { // ... }; Good:$scope.model = { menu: 'foo', nav: 'bar' }; const actions = function () { // ... }; Translation This is also available in other languages: Armenian: hanumanum/clean-code-javascript/ Bangla(বাংলা): InsomniacSabbir/clean-code-javascript/ Brazilian Portuguese: fesnt/clean-code-javascript Simplified Chinese: alivebao/clean-code-js beginor/clean-code-javascript Traditional Chinese: AllJointTW/clean-code-javascript French: GavBaros/clean-code-javascript-fr German: marcbruederlin/clean-code-javascript Indonesia: andirkh/clean-code-javascript/ Italian: frappacchio/clean-code-javascript/ Japanese: mitsuruog/clean-code-javascript/ Korean: qkraudghgh/clean-code-javascript-ko Polish: greg-dev/clean-code-javascript-pl Russian: BoryaMogila/clean-code-javascript-ru/ maksugr/clean-code-javascript Spanish: tureey/clean-code-javascript Spanish: andersontr15/clean-code-javascript Serbian: doskovicmilos/clean-code-javascript/ Turkish: bsonmez/clean-code-javascript Ukrainian: mindfr1k/clean-code-javascript-ua Vietnamese: hienvd/clean-code-javascript/
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    A Very Quick Guide To Calculating Big O Computational Complexity A Very Quick Guide To Calculating Big O Computational Complexity Big O: big picture, broad strokes, not details For a more complete guide… checkout : way we analyze how efficient algorithms are without getting too mired in details can model how much time any function will take given n inputs interested in order of magnitude of number of the exact figure O absorbs all fluff and n = biggest term Big O of 3x^2 +x + 1 = O(n^2) Time Complexity no loops or exit & return = O(1) 0 nested loops = O(n) 1 nested loops = O(n^2) 2 nested loops = O(n^3) 3 nested loops = O(n^4) recursive: as you add more terms, increase in time as you add input diminishes recursion: when you define something in terms of itself, a function that calls itself used because of ability to maintain state at diffferent levels of recursion inherently carries large footprint every time function called, you add call to stack iterative: use loops instead of recursion (preferred) - favor readability over performance O(n log(n)) & O(log(n)): dividing/halving if code employs recursion/divide-and-conquer strategy what power do i need to power my base to get n Time Definitions constant: does not scale with input, will take same amount of time for any input size n, constant time performs same number of operations every time logarithmic: increases number of operations it performs as logarithmic function of input size n function log n grows very slowly, so as n gets longer, number of operations the algorithm needs to perform doesn't increase very much halving linear: increases number of operations it performs as linear function of input size n number of additional operations needed to perform grows in direct proportion to increase in input size n log-linear: increases number of operations it performs as log-linear function of input size n looking over every element and doing work on each one quadratic: increases number of operations it performs as quadratic function of input size n exponential: increases number of operations it performs as exponential function of input size n number of nested loops increases as function of n polynomial: as size of input increases, runtime/space used will grow at a faster rate factorial: as size of input increases, runtime/space used will grow astronomically even with relatively small inputs rate of growth: how fast a function grows with input size Space Complexity How does the space usage scale/change as input gets very large? What auxiliary space does your algorithm use or is it in place (constant)? Runtime stack space counts as part of space complexity unless told otherwise. Data Structures & Algos In JS
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Await await The await operator is used to wait for a Promise. It can only be used inside an async function within regular JavaScript code; however it can be used on its own with JavaScript modules. Syntax[rv] = await expression; expression A Promise or any value to wait for. rv Returns the fulfilled value of the promise, or the value itself if it's not a Promise. Description The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment. When resumed, the value of the await expression is that of the fulfilled Promise. If the Promise is rejected, the await expression throws the rejected value. If the value of the expression following the await operator is not a Promise, it's converted to a resolved Promise. An await splits execution flow, allowing the caller of the async function to resume execution. After the await defers the continuation of the async function, execution of subsequent statements ensues. If this await is the last expression executed by its function, execution continues by returning to the function's caller a pending Promise for completion of the await's function and resuming execution of that caller. Examples Awaiting a promise to be fulfilled If a Promise is passed to an await expression, it waits for the Promise to be fulfilled and returns the fulfilled value. function resolveAfter2Seconds(x) { return new Promise(resolve => { setTimeout(() => { resolve(x); }, 2000); }); } async function f1() { var x = await resolveAfter2Seconds(10); console.log(x); // 10 } f1(); Thenable objects Thenable objects will be fulfilled just the same. async function f2() { const thenable = { then: function(resolve, _reject) { resolve('resolved!') } }; console.log(await thenable); // resolved! } f2(); Conversion to promise If the value is not a Promise, it converts the value to a resolved Promise, and waits for it. async function f3() { var y = await 20; console.log(y); // 20 } f3(); Promise rejection If the Promise is rejected, the rejected value is thrown. async function f4() { try { var z = await Promise.reject(30); } catch(e) { console.error(e); // 30 } } f4(); Handling rejected promises Handle rejected Promise without try block. var response = await promisedFunction().catch((err) => { console.error(err); }); // response will be undefined if the promise is rejected Top level await You can use the await keyword on its own (outside of an async function) within a JavaScript module. This means modules, with child modules that use await, wait for the child module to execute before they themselves run. All while not blocking other child modules from loading. Here is an example of a simple module using the Fetch API and specifying await within the export statement. Any modules that include this will wait for the fetch to resolve before running any code.// fetch request const colors = fetch('../data/colors.json') .then(response => response.json()); export default await colors;
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    AsynchAsynchronous JavaScript Asynchronous JavaScript Async functions: Let's start with the async keyword. It can be placed before a function, like this: async function f() { return 1; } The word "async" before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically. For instance, this function returns a resolved promise with the result of 1; let's test it: async function f() { return 1; } f().then(alert); // 1 ...We could explicitly return a promise, which would be the same: async function f() { return Promise.resolve(1); } f().then(alert); // 1 So, async ensures that the function returns a promise, and wraps non-promises in it. Simple enough, right? But not only that. There's another keyword, await, that works only inside async functions, and it's pretty cool. Await The syntax:// works only inside async functions let value = await promise; The keyword await makes JavaScript wait until that promise settles and returns its result. Here's an example with a promise that resolves in 1 second: async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve('done!'), 1000); }); let result = await promise; // wait until the promise resolves (*) alert(result); // "done!" } f(); The function execution "pauses" at the line (*) and resumes when the promise settles, with result becoming its result. So the code above shows "done!" in one second. Let's emphasize: await literally suspends the function execution until the promise settles, and then resumes it with the promise result. That doesn't cost any CPU resources, because the JavaScript engine can do other jobs in the meantime: execute other scripts, handle events, etc. It's just a more elegant syntax of getting the promise result than promise.then. And, it's easier to read and write. Can't use await in regular functions If we try to use await in a non-async function, there would be a syntax error: function f() { let promise = Promise.resolve(1); let result = await promise; // Syntax error } We may get this error if we forget to put async before a function. As stated earlier, await only works inside an async function. Let's take the showAvatar() example from the chapter Promises chaining and rewrite it using async/await: We'll need to replace .then calls with await. Also we should make the function async for them to work. async function showAvatar() { // read our JSON let response = await fetch('/article/promise-chaining/user.json'); let user = await response.json(); // read github user let githubResponse = await fetch(`https://api.github.com/users/${user.name}`); let githubUser = await githubResponse.json(); // show the avatar let img = document.createElement('img'); img.src = githubUser.avatar_url; img.className = 'promise-avatar-example'; document.body.append(img); // wait 3 seconds await new Promise((resolve, reject) => setTimeout(resolve, 3000)); img.remove(); return githubUser; } showAvatar(); Pretty clean and easy to read, right? Much better than before. await` won't work in the top-level code People who are just starting to use `await` tend to forget the fact that we can't use `await` in top-level code. For example, this will not work: ```js // syntax error in top-level code let response = await fetch('/article/promise-chaining/user.json'); let user = await response.json(); But we can wrap it into an anonymous async function, like this:(async () => { let response = await fetch('/article/promise-chaining/user.json'); let user = await response.json(); ... })(); P.S. New feature: starting from V8 engine version 8.9+, top-level await works in modules. await` accepts "thenables" Like `promise.then`, `await` allows us to use thenable objects (those with a callable `then` method). The idea is that a third-party object may not be a promise, but promise-compatible: if it supports `.then`, that's enough to use it with `await`. Here's a demo `Thenable` class; the `await` below accepts its instances: ```js class Thenable { constructor(num) { this.num = num; } then(resolve, reject) { alert(resolve); // resolve with this.num*2 after 1000ms setTimeout(() => resolve(this.num * 2), 1000); // (*) } } async function f() { // waits for 1 second, then result becomes 2 let result = await new Thenable(1); alert(result); } f(); If await gets a non-promise object with .then, it calls that method providing the built-in functions resolve and reject as arguments (just as it does for a regular Promise executor). Then await waits until one of them is called (in the example above it happens in the line (*)) and then proceeds with the result. Async class methods To declare an async class method, just prepend it with async: class Waiter { async wait() { return await Promise.resolve(1); } } new Waiter().wait().then(alert); // 1 (this is the same as (result => alert(result))) The meaning is the same: it ensures that the returned value is a promise and enables await.[Error handling] If a promise resolves normally, then await promise returns the result. But in the case of a rejection, it throws the error, just as if there were a throw statement at that line. This code: async function f() { await Promise.reject(new Error('Whoops!')); } ...is the same as this: async function f() { throw new Error('Whoops!'); } In real situations, the promise may take some time before it rejects. In that case there will be a delay before await throws an error. We can catch that error using try..catch, the same way as a regular throw: async function f() { try { let response = await fetch('http://no-such-url'); } catch (err) { alert(err); // TypeError: failed to fetch } } f(); In the case of an error, the control jumps to the catch block. We can also wrap multiple lines: async function f() { try { let response = await fetch('/no-user-here'); let user = await response.json(); } catch (err) { // catches errors both in fetch and response.json alert(err); } } f(); If we don't have try..catch, then the promise generated by the call of the async function f() becomes rejected. We can append .catch to handle it: async function f() { let response = await fetch('http://no-such-url'); } // f() becomes a rejected promise f().catch(alert); // TypeError: failed to fetch // (*) If we forget to add .catch there, then we get an unhandled promise error (viewable in the console). We can catch such errors using a global unhandledrejection event handler as described in the chapter Error handling with promises. async/await` and `promise.then/catch When we use async/await, we rarely need .then, because await handles the waiting for us. And we can use a regular try..catch instead of .catch. That's usually (but not always) more convenient. But at the top level of the code, when we're outside any async function, we're syntactically unable to use await, so it's a normal practice to add .then/catch to handle the final result or falling-through error, like in the line (*) of the example above. async/await` works well with `Promise.all When we need to wait for multiple promises, we can wrap them in Promise.all and then await:// wait for the array of results let results = await Promise.all([ fetch(url1), fetch(url2), ... ]); In the case of an error, it propagates as usual, from the failed promise to Promise.all, and then becomes an exception that we can catch using try..catch around the call. Summary The async keyword before a function has two effects: Makes it always return a promise. Allows await to be used in it. The await keyword before a promise makes JavaScript wait until that promise settles, and then: If it's an error, the exception is generated --- same as if throw error were called at that very place. Otherwise, it returns the result. Together they provide a great framework to write asynchronous code that is easy to both read and write. With async/await we rarely need to write promise.then/catch, but we still shouldn't forget that they are based on promises, because sometimes (e.g. in the outermost scope) we have to use these methods. Also Promise.all is nice when we are waiting for many tasks simultaneously. Cleaning up your asynchronous code with await REPLs have traditionally had a difficult time allowing you to interact with asynchronous code since they encourage a coding style where you evaluate expressions and use those results in the next field. But if you are using promises or callbacks, this breaks down because these results exist only in the callback, not the next line: In RunKit, you can use top-level await to get the same behavior of synchronous code. Now we can treat this code as synchronous, despite the fact that the code is still executing asynchronously. Let's look how. It helps to have a more complex example, where we need to do a few asynchronous operations in sequence. You can see how await, promises and callbacks achieve the same results, but the await style works better in a REPL: await promises callbacks Here, we use await on lines 4 and 8, and the results from each request remain in scope. Remember, await expects a promise so you can either write your own or use one of the many libraries that natively supports promises, and npm is full of packages that add promise support to existing libraries. Here are a few of our favorites: fs-promise - promise based filesystem api request-promise - a wrapper around "request" for http stuff glob-promise - glob style filesystem queries bluebird - general promise library with lots of utilities Further Reading ES7 Async/Await presented at Brookyln.js Babel.js ECMAScript's Proposal for async/await ES Meeting Notes discussing on async/await Does async/await Solve a Real Problem? The Long Road to async/await in JavaScript async/await: The Hero JavaScript Deserved
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    JS Fat Arrow Functions JS Fat Arrow Functions Classical JavaScript function syntax doesn't provide for any flexibility, be that a 1 statement function or an unfortunate multi-page function. Every time you need a function you have to type out the dreaded function () {}. More concise function syntax was one of the many reasons why CoffeeScript gained so much momentum back in the day. This is especially pronounced in the case of tiny callback functions. Lets look at a Promise chain: function getVerifiedToken(selector) { return getUsers(selector) .then(function (users) { return users[0]; }) .then(verifyUser) .then(function (user, verifiedToken) { return verifiedToken; }) .catch(function (err) { log(err.stack); }); } Above is more or less plausible piece of code written using classical JavaScript function syntax. Here is what the same code could look like rewritten using the arrow syntax: function getVerifiedToken(selector) { return getUsers(selector) .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack)); } A few important things to notice here: We've lost function and {} because all of our callback functions are one liners. We've lost () around the argument list when there's just one argument (rest arguments are an exception, eg (...args) => ...) We've lost the return keyword because when omitting {}, single line arrow functions perform an implicit return (these functions are often referred to as lambda functions in other languages). It's important to reinforce the last point. Implicit return only happens for single statement arrow functions. When arrow function is declared with {}, even if it's a single statement, implicit return does not happen: const getVerifiedToken = selector => { return getUsers() .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack)); } Here's the really fun bit. Because our function has only one statement, we can still get rid of the {} and it will look almost exactly like CoffeeScript syntax: const getVerifiedToken = selector => getUsers() .then(users => users[0]) .then(verifyUser) .then((user, verifiedToken) => verifiedToken) .catch(err => log(err.stack)); Yep, the example above is completely valid ES2015 syntax (I was also surprised that it compiles fine). When we talk about single statement arrow functions, it doesn't mean the statement can't be spread out to multiple lines for better comprehension. There's one caveat, however, with omitting {} from arrow functions -- how do you return an empty object, eg {}? const emptyObject = () => {}; emptyObject(); // ? Unfortunately there's no way to distinguish between empty block {} and an object {}. Because of that emptyObject() evaluates to undefined and {} interpreted as empty block. To return an empty object from fat arrow functions you have to surround it with brackets like so ({}): const emptyObject = () => ({}); emptyObject(); // {} Here's all of the above together: function () { return 1; } () => { return 1; } () => 1 function (a) { return a * 2; } (a) => { return a * 2; } (a) => a * 2 a => a * 2 function (a, b) { return a * b; } (a, b) => { return a * b; } (a, b) => a * b function () { return arguments[0]; } (...args) => args[0] () => {} // undefined () => ({}) // {} Lexical this The story of clobbering this in JavaScript is a really old one. Each function in JavaScript defines its own this context, which is as easy to get around as it is annoying. The example below tries to display a clock that updates every second using jQuery:$('.current-time').each(function () { setInterval(function () { $(this).text(Date.now()); }, 1000); }); When attempting to reference the DOM element this set by each in the setInterval callback, we unfortunately get a brand new this that belongs to the callback itself. A common way around this is to declare that or self variable:$('.current-time').each(function () { var self = this; setInterval(function () { $(self).text(Date.now()); }, 1000); }); The fat arrow functions allow you to solve this problem because they don't introduce their own this:$('.current-time').each(function () { setInterval(() => $(this).text(Date.now()), 1000); }); What about arguments? One of the caveats with arrow functions is that they also don't have their own arguments variable like regular functions: function log(msg) { const print = () => console.log(arguments[0]); print(`LOG: ${msg}`); } log('hello'); // hello To reiterate, fat arrow functions don't have their own this and arguments. Having said that, you can still get all arguments passed into the arrow functions using rest parameters (also known as spread operator): function log(msg) { const print = (...args) => console.log(args[0]); print(`LOG: ${msg}`); } log('hello'); // LOG: hello What about yield? Fat arrow functions can't be used as generators. That's it -- no exceptions, no caveats and no workarounds. Bottom Line Fat arrow functions are one of my favorite additions to JavaScript. It might be very tempting to just start using => instead of function everywhere. I've seen whole libraries written just using => and I don't think it's the right thing to do because of the special features that => introduces. I recommend using arrow functions only in places where you explicitly want to use the new features: Single statement functions that immediately return (lambdas) Functions that need to work with parent scope this
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Review Of Concepts Review-Of-Previous-Concepts Review of Concepts Running JS Locally Concepts Match the commands ls, cd, pwd to their descriptions ls lists contents of current directory cd changes current directory cd .. takes you up one level cd alone takes you back home pwd returns current directory Given a folder structure diagram, a list of 'cd (path)' commands and target files, match the paths to the target files. Use VSCode to create a folder. Within the folder create a .js file containing console.log('hello new world'); and save it. Use node to execute a JavaScript file in the terminal Plain Old JS Object Lesson Concepts Label variables as either Primitive vs. Reference primitives: strings, booleans, numbers, null and undefined primitives are immutable refereces: objects (including arrays) references are mutable Identify when to use . vs [] when accessing values of an object dot syntax object.key easier to read easier to write cannot use variables as keys keys cannot begin with a number bracket notation object["key] allows variables as keys strings that start with numbers can be use as keys Write an object literal with a variable key using interpolation put it in brackets to access the value of the variable, rather than just make the value that string let a = "b"; let obj = { a: "letter_a", [a]: "letter b" }; Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object can also use (key in object) syntax interchangeably (returns a boolean) Utilize Object.keys and Object.values in a function Object.keys(obj) returns an array of all the keys in obj Object.values(obj) returns an array of the values in obj Iterate through an object using a for in loop let printValues = function (obj) { for (let key in obj) { let value = obj[key]; console.log(value); } }; Define a function that utilizes ...rest syntax to accept an arbitrary number of arguments...rest syntax will store all additional arguments in an array array will be empty if there are no additional arguments let myFunction = function (str, ...strs) { console.log("The first string is " + str); console.log("The rest of the strings are:"); strs.forEach(function (str) { console.log(str); }); }; Use ...spread syntax for Object literals and Array literals let arr1 = ["a", "b", "c"]; let longer = [...arr1, "d", "e"]; // ["a", "b", "c", "d", "e"] // without spread syntax, this would give you a nested array let withoutRest = [arr1, "d", "e"]; // [["a", "b", "c"], "d", "e"] Destructure an array to reference specific elements let array = \[35,9\]; let \[firstEl, secondEl\] = array; console.log\(firstEl\); // =&gt; 35 console.log\(secondEl\); // =&gt; 9 > can also destructure using ... syntax let array = \[35,9,14\]; let \[head, ...tail\] = array; console.log\(head\); // =&gt; 35 console.log\(tail\); // =&gt; \[9, 14\] ```js - Destructure an object to reference specific values - if you want to use variable names that don't match the keys, you can use aliasing - `let { oldkeyname: newkeyname } = object` - rule of thumb—only destructure values from objects that are two levels deep ```js let obj = { name: "Wilfred", appearance: ["short", "mustache"], favorites: { color: "mauve", food: "spaghetti squash", number: 3 } } // with variable names that match keys let { name, appearance } = obj; console.log(name); // "Wilfred" console.log(appearance); // ["short", "mustache"] > with new variable names (aliasing) let {name: myName, appearance: myAppearance} = obj; console.log(myName); // "Wilfred" console.log(myAppearance); // ["short", "mustache"] > in a function call let sayHello = function({name}) { console.log("Hello, " + name); // "Hello Wilfred" } // nested objects + aliasing let { favorites: {color, food: vegetable} } = obj; console.log(color, vegetable); //=> mauve spaghetti squash Write a function that accepts a array as an argument and returns an object representing the count of each character in the array// let elementCounts = function (array) { let obj = {}; array.forEach(function (el) { if (el in obj) obj[el] += 1; else obj[el] = 1; }); return obj; }; console.log(elementCounts(["e", "f", "g", "f"])); // => Object {e: 1, f: 2, g: 1} Callbacks Lesson Concepts Given multiple plausible reasons, identify why functions are called "First Class Objects" in JavaScript. they can be stored in variables, passed as arguments to other functions, and serve as return value for a function supports same basic operations as other types (strings, bools, numbers) higher-order functions take functions as arguments or return functions as values Given a code snippet containing an anonymous callback, a named callback, and multiple console.log s, predict what will be printed what is this referring to? Write a function that takes in a value and two callbacks. The function should return the result of the callback that is greater. let greaterCB = function (val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); }; let greaterCB = function (val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); }; shorter version let greaterCB = function(val, callback1, callback2) { return Math.max(callback1(val), callback2(val)); } // even shorter, cause why not let greaterCB = (val, cb1, cb2) => Math.max(cb1(val), cb2(val));- Write a function, myMap, that takes in an array and a callback as arguments. The function should mimic the behavior of `Array#map`. ```js let myMap = function(array, callback) { let newArr = []; for (let i = 0; i < array.length; i ++) { mapped = callback(array[i], i, array); newArr.push(mapped); } return newArr; } console.log( myMap([16,25,36], Math.sqrt)); // => [4, 5, 6]; let myMapArrow = (array, callback) => { let newArr = []; array.forEach( (ele, ind, array) => { newArr.push(callback(ele, ind, array)); }) return newArr; } console.log(myMapArrow([16,25,36], Math.sqrt)); // => [4, 5, 6]; Write a function, myFilter, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#filter. let myFilter = function (array, callback) { let filtered = []; for (let i = 0; i < array.length; i++) { if (callback(array[i])) { filtered.push(array[i], i, array); } } }; Write a function, myEvery, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#every. let myEvery = function (array, callback) { for (let i = 0; i < array.length; i++) { if (!callback(array[i], i, array)) { return false; } } return true; }; // with arrow function syntax let myEvery = (array, callback) => { for (let i = 0; i < array.length; i++) { if (!callback(array[i])) { return false; } } return true; }; Scope Lesson Concepts Identify the difference between const, let, and var declarations const - cannot reassign variable, scoped to block let - can reassign variable, scoped to block var - outdated, may or may not be reassigned, scoped to function. can be not just reassigned, but also redeclared! a variable will always evaluate to the value it contains regardless of how it was declared Explain the difference between const, let, and var declarations var is function scoped—so if you declare it anywhere in a function, the declaration (but not assignment) is "hoisted" so it will exist in memory as "undefined" which is bad and unpredictable var will also allow you to redeclare a variable, while let or const will raise a syntax error. you shouldn't be able to do that! const won't let you reassign a variable, but if it points to a mutable object, you will still be able to change the value by mutating the object block-scoped variables allow new variables with the same name in new scopes block-scoped still performs hoisting of all variables within the block, but it doesn't initialize to the value of undefined like var does, so it throws a specific reference error if you try to access the value before it has been declared if you do not use var or let or const when initializing, it will be declared as global—THIS IS BAD if you assign a value without a declaration, it exists in the global scope (so then it would be accessible by all outer scopes, so bad). however, there's no hoisting, so it doesn't exist in the scope until after the line is run Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining scope of a program means the set of variables that are available for use within the program global scope is represented by the window object in the browser and the global object in Node.js global variables are available everywhere, and so increase the risk of name collisions local scope is the set of variables available for use within the function when we enter a function, we enter a new scope includes functions arguments, local variables declared inside function, and any variables that were already declared when the function is defined (hmm about that last one) for blocks (denoted by curly braces {}, as in conditionals or for loops), variables can be block scoped inner scope does not have access to variables in the outer scope scope chaining—if a given variable is not found in immediate scope, javascript will search all accessible outer scopes until variable is found so an inner scope can access outer scope variables but an outer scope can never access inner scope variables Define an arrow function let arrowFunction = \(param1, param2\) =&gt; { let sum = param1 + param2; return sum; } // with 1 param you can remove parens around parameters let arrowFunction = param =&gt; { param += 1; return param; } // if your return statement is one line, you can use implied return let arrowFunction = param =&gt; param + 1; > you don't have to assign to variable, can be anonymous // if you never need to use it again param =&gt; param + 1; Given an arrow function, deduce the value of this without executing the code arrow functions are automatically bound to the context they were declared in unlike regular function which use the context they are invoked in (unless they have been bound using Function#bind) if you implement an arrow function as a method in an object the context it will be bound to is NOT the object itself, but the global context so you can't use an arrow function to define a method directly let obj = { name: "my object", unboundFunc: function \(\) { return this.name; // this function will be able to be called on different objects }, ### boundToGlobal: \(\) =&gt; { return this.name; // this function, no matter how you call it, will be called // on the global object, and it cannot be rebound // this is because it was defined using arrow syntax }, ```js makeFuncBoundToObj: function () { return () => { return this.name; } // this function will return a function that will be bound // to the object where we call the outer method // because the arrow syntax is nested inside one of this // function's methods, it cannot be rebound }, makeUnboundFunc: function () { return function () { return this.name; } //this function will return a function that will still be unbound }, immediatelyInvokedFunc: function () { return this.name; }(), // this property will be set to the return value of this anonymous function, > which is invoked during the object definition; > basically, it's a way to check the context inside of an object, at this moment innerObj: { name: "inner object", innerArrowFunc: () => { return this.name; } // the context inside a nested object is not the parent, it's still // the global object. entering an object definition doesn't change the context }, let otherObj = { name: "my other object" } // call unboundFunc on obj, we get "my object" console.log("unboundFunc: ", obj.unboundFunc()); // => "my object" // assign unboundFunc to a variable and call it let newFunc = obj.unboundFunc; // this newFunc will default to being called on global object console.log("newFunc: ",newFunc()); // => undefined // but you could bind it directly to a different object if you wanted console.log("newFunc: ", newFunc.bind(otherObj)()); // "my other object" > meanwhile, obj.boundToGlobal will only ever be called on global object console.log("boundToGlobal: ", obj.boundToGlobal()); //=> undefined let newBoundFunc = obj.boundToGlobal; console.log("newBoundFunc: ", newBoundFunc()); // => undefined // even if you try to directly bind to another object, it won't work! console.log("newBoundFunc: ", newBoundFunc.bind(otherObj)()); // => undefined > let's make a new function that will always be bound to the context // where we call our function maker let boundFunc = obj.makeFuncBoundToObj();// note that we're invoking, not just assigning console.log("boundFunc: ", boundFunc()); // => "my object" // we can't rebind this function console.log("boundFunc: ", boundFunc.bind(otherObj)()) // =>"my object" > but if I call makeFuncBoundToObj on another context // the new bound function is stuck with that other context let boundToOther = obj.makeFuncBoundToObj.bind(otherObj)(); console.log("boundToOther: ", boundToOther()); // => "my other object" console.log("boundToOther: ", boundToOther.bind(obj)()) // "my other object" > the return value of my immediately invoked function // shows that the context inside of the object is the // global object, not the object itself // context only changes inside a function that is called // on an object console.log("immediatelyInvokedFunc: ", obj.immediatelyInvokedFunc); // => undefined > even though we're inside a nested object, the context is // still the same as it was outside the outer object // in this case, the global object console.log("innerArrowFunc: ", obj.innerObj.innerArrowFunc()); // => undefined }- Implement a closure and explain how the closure effects scope - a closure is "the combination of a function and the lexical environment within which that function was declared" - alternatively, "when an inner function uses or changes variables in an outer function" - closures have access to any variables within their own scope + scope of outer functions + global scope — the set of all these available variables is "lexical environemnt" - closure keeps reference to all variables **even if the outer function has returned** - each function has a private mutable state that cannot be accessed externally - the inner function will maintain a reference to the scope in which it was declared. so it has access to variables that were initialized in any outer scope—even if that scope - if a variable exists in the scope of what could have been accessed by a function (e.g. global scope, outer function, etc), does that variable wind up in the closure even if it never got accessed? - if you change the value of a variable (e.g. i++) you will change the value of that variable in the scope that it was declared in ```js function createCounter() { // this function starts a counter at 0, then returns a // new function that can access and change that counter // // each new counter you create will have a single internal // state, that can be changed only by calling the function. // you can't access that state from outside of the function, // even though the count variable in question is initialized // by the outer function, and it remains accessible to the // inner function after the outer function returns. let count = 0; return function() { count ++; return count; } } let counter = createCounter(); console.log(counter()); //=> 1 console.log(counter()); //=> 2 > so the closure here comes into play because > an inner function is accessing and changing > a variable from an outer function > the closure is the combination of the counter > function and the all the variables that existed > in the scope that it was declared in. because > inner blocks/functions have access to outer > scopes, that includes the scope of the outer > function. > so counter variable is a closure, in that > it contains the inner count value that was > initialized by the outer createCounter() function > count has been captured or closed over > this state is private, so if i run createCounter again > i get a totally separate count that doesn't interact > with the previous one and each of the new functions > will have their own internal state based on the > initial declaration in the now-closed outer function let counter2 = createCounter(); console.log(counter2()); // => 1 > if i set a new function equal to my existing counter > the internal state is shared with the new function let counter3 = counter2; console.log(counter3()); Define a method that references this on an object literal when we use this in a method it refers to the object that the method is invoked on it will let you access other pieces of information from within that object, or even other methods method style invocation - object.method(args) (e.g. built in examples like Array#push, or String#toUpperCase) context is set every time we invoke a function function style invocation sets the context to the global object no matter what being inside an object does not make the context that object! you still have to use method-style invocation Utilize the built in Function#bind on a callback to maintain the context of this when we call bind on a function, we get an exotic function back—so the context will always be the same for that new function text let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function // we can use the built in Function.bind to ensure our context, our this, // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints "meow" \`\` - `bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context. the first arg will be the context aka the `this` you want it to use. the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope (which itself has pointers to new scopes until you reach the global scope. so you can think about a whole given block's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function - so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object's method on something other than that object, and then this would refer to the context where/how it was called, e.g. ```js let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; > note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined > our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn't exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object text let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; global.setTimeout(cat.purrMore, 5000); // 5 seconds later: TypeError: this.purr is not a function we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function we can use the built in Function.bind to ensure our context, our this, // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints "meow" text - `bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context. the first arg will be the context aka the `this` you want it to use. the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope (which itself has pointers to new scopes until you reach the global scope. so you can think about a whole given block's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function - so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object's method on something other than that object, and then this would refer to the context where/how it was called, e.g. ```js let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; > note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined > our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn't exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object let cat = { purr: function \(\) { console.log\("meow"\); }, purrMore: function \(\) { this.purr\(\); }, }; global.setTimeout\(cat.purrMore, 5000\); // 5 seconds later: TypeError: this.purr is not a function we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined POJOs 1. Label variables as either Primitive vs. Reference Javascript considers most data types to be 'primitive', these data types are immutable, and are passed by value. The more complex data types: Array and Object are mutable, are considered 'reference' data types, and are passed by reference. Boolean - Primitive Null - Primitive Undefined - Primitive Number - Primitive String - Primitive Array - Reference Object - Reference Function - Reference 2. Identify when to use . vs [] when accessing values of an object let obj = { one: 1, two: 2 }; > Choose the square brackets property accessor when the property name is determined at > runtime, or if the property name is not a valid identifier let myKey = 'one'; console.log(obj[myKey]); > Choose the dot property accessor when the property name is known ahead of time. console.log(obj.two); 3. Write an object literal with a variable key using interpolation let keyName = 'two'; > If the key is not known, you can use an alternative `[]` syntax for > object initialization only let obj2 = { [keyName]: 2 }; console.log(obj2); 4. Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object function doesKeyExist(obj, key) { // obj[key] !== undefined // or: return key in obj; } let course = { bootcamp: "Lambda", course: "Bootcamp Prep" }; console.log(doesKeyExist(course, "course")); // => true console.log(doesKeyExist(course, "name")); // => false 5. Utilize Object.keys and Object.values in a function function printKeys(object) { return Object.keys(object); } function printValues(object) { return Object.values(object); } console.log(printKeys({ dog: "Strelka", dog2: "Belka" })); console.log(printValues({ dog: "Strelka", dog2: "Belka" })); 6. Iterate through an object using a for in loop let player = { name: "Sergey", skill: "hockey" }; for (let key in player) { console.log(key, player[key]); } console.log(Object.entries(player)); 7. Define a function that utilizes ...rest syntax to accept an arbitrary number of arguments function restSum(...otherNums) { let sum = 0; console.log(otherNums); otherNums.forEach(function (num) { sum += num; }); return sum; } console.log(restSum(3, 5, 6)); // => 14 console.log(restSum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // => 45 console.log(restSum(0)); // => 0 8. Use ...spread syntax for Object literals and Array literals let numArray = [1, 2, 3]; let moreNums = [...numArray, 4, 5, 6]; console.log(moreNums); let shoe = { color: "red", size: 10 }; let newShoe = { ...shoe, brand: "Nike", size: 12 }; console.log(newShoe); newShoe.color = "black"; console.log(newShoe); console.log(shoe); 9. Destructure an array to reference specific elements let arr = ["one", "two", "three"]; let [first] = arr; console.log(first); 10. Destructure an object to reference specific values let me = { name: "Ian", instruments: ["bass", "synth", "guitar"], siblings: { brothers: ["Alistair"], sisters: ["Meghan"], }, }; let { name, instruments: musical_instruments, siblings: { sisters }, } = me; console.log(name); console.log(musical_instruments); console.log(sisters); 11. Write a function that accepts a string as an argument and returns an object representing the count of each character in the array function charCount(inputString) { let res = inputString.split("").reduce(function (accum, el) { if (el in accum) { accum[el] = accum[el] + 1; } else { accum[el] = 1; } return accum; }, {}); return res; } console.log(charCount("aaabbbeebbcdkjfalksdfjlkasdfasdfiiidkkdingds")); Review of Concepts 1. Identify the difference between const, let, and var declarations 2. Explain the difference between const, let, and var declarations var a = "a"; var is the historical keyword used for variable declaration. var declares variables in function scope, or global scope if not inside a function. We consider var to be deprecated and it is never used in this course. let b = "b"; let is the keyword we use most often for variable declaration. let declares variables in block scope. variables declared with let are re-assignable. const c = "c"; const is a specialized form of let that can only be used to initialize a variable. Except when it is declared, you cannot assign to a const variable. const scopes variables the same way that let does. 3. Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining Consider this run function, inside which foo and bar have function scope. i and baz are scoped to the block expression.> function and block scope in this example function run() { var foo = 'Foo'; let bar = 'Bar'; console.log(foo, bar); { console.log(foo); let baz = 'Bazz'; console.log(baz); } console.log(baz); // ReferenceError } run(); Notice that referencing baz from outside it's block results in JavaScript throwing a ReferenceError. Consider this run function, inside of which foo has function scope. function run() { console.log(foo); // undefined var foo = "Foo"; console.log(foo); // Foo } run(); Consider this func1 function and it's nested scopes.> global scope function func1(arg1) { // func1 scope return function func2(arg2) { // func2 scope return function func3(arg3) { // func3 scope console.log(arg1, arg2, arg3); }; }; } 6. Implement a closure and explain how the closure effects scope const adder = (arg1) => { return (arg2) => { return arg1 + arg2; }; }; const func2 = adder(2); const result = func2(2); console.log(result); // => 4; 4. Define an arrow function const returnValue = (val) => val; This simple construct will create a function that accepts val as a parameter, and returns val immediately. We do not need to type return val, because this is a single-line function. Identically, we could write const returnValue = (val) => { return val; }; 5. Given an arrow function, deduce the value of this without executing the code function fDAdder(arr) { console.log(this); return arr.reduce((acc, ele) => { return acc + ele; }); } fDAdder([1, 2, 4, 6]); If we use a function declaration style function, the this variable is set to the global object (i.e. Object [global] in Node.JS and Window in your browser). const adder = (arr) => { console.log(this); arr.reduce((acc, ele) => (sum += ele)); }; adder([1, 2, 4, 6]); In this example, we use a fat arrow style function. Note that when we declare a funciton like this this becomes 7. Define a method that references this on an object literal const pokemon = { firstname: "Pika", lastname: "Chu", getPokeName: function () { const fullname = `${this.firstname} ${this.lastname}`; return fullname; }, }; console.log(pokemon.getPokeName()); 8. Utilize the built in Function#bind on a callback to maintain the context of this const pokemon = { firstname: "Pika", lastname: "Chu", getPokeName: function () { const fullname = `${this.firstname} ${this.lastname}`; return fullname; }, }; const logPokemon = pokemon.getPokename.bind(pokemon); logPokemon("sushi", "algorithms"); // Pika Chu loves sushi and algorithms 9. Given a code snippet, identify what this refers to function Person(name) { // this.name = name; // let that = this; setTimeout(function () { // console.log(this); // => Window // console.log(that); // => [Function] => Person // this.sayName(); // => no method error that.sayName(); }, 1000); } Person.prototype.sayName = function () { console.log(this.name); }; const jane = new Person("Jane");
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Job Search Navigation Navigation🏡 Home🗺 Navigation📥 Useful Downloads🛠 Skills My Stack🙏 Resources Orientation: Links Practice Problems:❄ Cold Outreach Generator Running List Of MISC Resources: Resume📰 Resume Examples Advice Cover Letter📒 Cover Letter Example Of Developer Bio Portfolio💼 Showcase💾 Git Repo🖼 Portfolio📈 Slack&Lambda📍 Pinned Items:📌 Pinned Messages:❇ Slack Announcements📺 Recordings🧑🤝🧑 People Aux-Resources Youtube🖋 Interview Prep⁉ Interview Questions. Cheat Sheets Python-VS-JS Cheat Sheet Common Knowledge Questions Types Of Data Structures👨💻 Leetcode: Hash Tables DS_ALGO Practice: Python Subpage🐍 Python More Practice: Tutorials Job Search Guide Common Questions Self Introduction Getting Started Applications & Job Postings👔 Postings: My Applications😅 Jobs I Really Want Stackbit Developer Advocate (Remote) Page 4 Emails Job Boards📋 Job Boards Less Promising Job Boards LIST OF BOARDS Networking🗓 Events Lambda Guidance & Meetings📥 Meetings: MISC🗞 Articles To Read Notes📓 Notes Page 5🖨 Interviewing General🖥 JS
    https://bgoonz-blog.netlify.app/images/code.png
  • Zumzi Video Conference:
    Zumzi Video Conferencing (Mesibo API Backend) Zumzi Video Conference: Zumzi Live Demo Features: Group Voice and Video Call with unlimited members Live Streaming Screen Sharing Fine control over all video & audio parameters and user permissions Supports video streaming at various resolutions: Standard, HD, FHD and 4K Group Chat One-to-One chat Invite Participants There are two sub-folders: backend contains the source code for hosting the backend APIs for the app web contains the source code for the app which you can directly integrate into your website. Apendix access token: An Access Token needs to be generated for every user who needs to access mesibo real-time messaging API. You can generate Access Token for every user of your application on demand and send it to the user. The user will then use this access token to initialize mesibo client-side API.. api key API key is a unique alphanumeric identifier associated with your Mesibo account. You can view, change or regenerate the API key from the Mesibo console. Application Token is a unique alphanumeric identifier with one of your application. You can view and change the app token from the Mesibo Console. Mesibo container A container is a runtime instance of mesibo in-premises docker image. MAU MAU is counted when a user connects to mesibo server within monthly billing period. To further clarify, it will be only counted as one when a unique user connects to mesibo server multiple times within monthly billing period High-availability clusters(also known as HA clusters or fail-over clusters) are groups of computers that support server applications that can be reliably utilized with a minimum amount of down-time namespace in mesibo is refer to a mesibo feature that isolates users and groups of an application from another application. Users can only interact with users and groups of the same application that are part of the same namespace. Namespaces are an important part of Mesibo's isolation model node A [node]is a physical or virtual machine running an instance of the mesibo. On premises deployment Mesibo On-premises deploment allows you to run Mesibo in your own data center or cloud. 1-1 Communication Communication is between two parties; for example, a chat or a call Peer-to-peer (P2P) It is a distributed application architecture that partitions tasks or workloads between peers. Peers are equally privileged, equipotent participants in the application.They are said to form a peer-to-peer network of nodes.. ├── ./backend │ ├── ./backend/activation.php │ ├── ./backend/api_functions.php │ ├── ./backend/api.php │ ├── ./backend/captcha.php │ ├── ./backend/config.php │ ├── ./backend/consts.php │ ├── ./backend/db.sql │ ├── ./backend/errorhandler.php │ ├── ./backend/httpheaders.php │ ├── ./backend/image.php │ ├── ./backend/json.php │ ├── ./backend/mesiboapi.php │ ├── ./backend/mesibohelper.php │ ├── ./backend/mysqldb.php │ ├── ./backend/mysql-wrapper.php │ ├── ./backend/README.md │ ├── ./backend/upload.php │ └── ./backend/utility.php ├── ./glossary_files │ ├── ./glossary_files/559862854355634.js │ ├── ./glossary_files/analytics.js │ ├── ./glossary_files/archive.js │ ├── ./glossary_files/bootstrap.min.css │ ├── ./glossary_files/bootstrap.min.js │ ├── ./glossary_files/buttons.js │ ├── ./glossary files/collections tocs.js │ ├── ./glossary_files/css.css │ ├── ./glossary_files/docs.js │ ├── ./glossary_files/fbevents.js │ ├── ./glossary_files/font-awesome.min.css │ ├── ./glossary_files/github.css │ ├── ./glossary_files/glossary.js │ ├── ./glossary_files/jquery.js │ ├── ./glossary_files/menu.js │ ├── ./glossary_files/mesibo-logo.svg │ ├── ./glossary_files/mesibo-logo-white.png │ ├── ./glossary_files/metadata.js │ ├── ./glossary_files/perldoc.css │ ├── ./glossary_files/stickyfill.min.js │ ├── ./glossary_files/style.css │ └── ./glossary_files/toc.js ├── ./glossary.html ├── ./index.html ├── ./package-lock.json ├── ./README.md ├── ./scrap.md ├── ./tree.md ├── ./TREE.md ├── ./web │ ├── ./web/assets │ │ ├── ./web/assets/audio │ │ │ ├── ./web/assets/audio/join.mp3 │ │ │ └── ./web/assets/audio/join.ogg │ │ ├── ./web/assets/fonts │ │ │ └── ./web/assets/fonts/font-awesome │ │ │ └── ./web/assets/fonts/font-awesome/css │ │ │ └── ./web/assets/fonts/font-awesome/css/font-awesome.css │ │ ├── ./web/assets/images │ │ │ ├── ./web/assets/images/blank-white.jpg │ │ │ ├── ./web/assets/images/file │ │ │ │ └── ./web/assets/images/file/default file icon.jpg │ │ │ ├── ./web/assets/images/mesibo-logo-m.png │ │ │ ├── ./web/assets/images/mesibo-logo.png │ │ │ ├── ./web/assets/images/profile │ │ │ │ ├── ./web/assets/images/profile/default-group-icon.jpg │ │ │ │ └── ./web/assets/images/profile/default-profile-icon.jpg │ │ │ └── ./web/assets/images/social.png │ │ └── ./web/assets/scripts │ │ └── ./web/assets/scripts/platform.js │ ├── ./web/index.html │ ├── ./web/listing.md │ ├── ./web/login.html │ ├── ./web/mesibo │ │ ├── ./web/mesibo/app.js │ │ ├── ./web/mesibo/calls.js │ │ ├── ./web/mesibo/config.js │ │ ├── ./web/mesibo/files.js │ │ ├── ./web/mesibo/notify.js │ │ └── ./web/mesibo/utils.js │ ├── ./web/README.md │ ├── ./web/scripts │ │ ├── ./web/scripts/app-utils.js │ │ ├── ./web/scripts/controller.js │ │ └── ./web/scripts/login.js │ ├── ./web/styles │ │ ├── ./web/styles/live.css │ │ ├── ./web/styles/mesibolive.css │ │ ├── ./web/styles/popup.css │ │ └── ./web/styles/popupdesign.css │ └── ./web/vendor │ ├── ./web/vendor/bootstrap.min.css │ └── ./web/vendor/bootstrap.min.js └── ./zumzi-video-chat.PNG Messenger Edit config.js and provide the AUTH TOKEN & APP ID. You can obtain the AUTH TOKEN and APP ID for a user from Mesibo Console. Refer to the Get-Started Guide to learn about the basics of mesibo. To open messenger demo launch messenger.html const MESIBO_ACCESS_TOKEN = 'xxxxxxx'; const MESIBO_APP_ID = 'xxxx'; const MESIBO_API_URL = 'https://app.mesibo.com/api.php'; If you are hosting mesibo-backend on your own server, you need to change the API URL to point to your server. Messenger Login You can synchronize contacts, by using a phone number to login to mesibo messenger-javascript. To login to the mesibo messenger web app, in the login screen provide the phone number along with country code starting with + For Example, If your country code is 91 and your ten-digit phone number is XXXXXXXXXX, enter your phone number as +91XXXXXXXXXX (with out any spaces or special characters in between) Use OTP 123456 to login. Mesibo will generate and store MESIBO_ACCESS_TOKEN if login is successful. Please note that you only need to login once as for later sessions your token will be stored in local storage. If you DO NOT wish to login with your phone number, make sure you configure a valid MESIBO_ACCESS_TOKEN in config.js and set isLoginEnabled = false Synchronizing contacts on Messenger To synchronize contacts set isContactSync = true For the best experience using the messenger app, make sure you have some contacts who are using Mesibo Messenger. These contacts will be displayed as a list of available users to whom you can send messages or make calls. Optionally, you can also manually provide a list of phone numbers of contacts who are using mesibo in MESIBO_LOCAL_CONTACTS or by clicking on the Add Contact button. You can provide a list of local contacts that will be loaded as a list of available users. Set local contacts as follows in config.js var MESIBO_LOCAL_CONTACTS =[ { "address" : "18885551001", "groupid" : 0, "picture" : "images/profile/default-profile-icon.jpg", "name" : "MesiboTest", "status": "Let's Chat.." }, { "groupid" : 104661, "picture" : "images/profile/default-group-icon.jpg", "name" : "Mesibo Group", "members" : "1:123,456,789" //Members list. Add 1: to mark as admin }, ] Popup To launch popup demo you can configure the following for setting the displayed user avatar and destination user(to which all messages will be sent) in config.js and launch popup.html const POPUP_DISPLAY_NAME = 'xxxx'; const POPUP_DISPLAY_PICTURE = 'images/profile/default-profile-icon.jpg'; const POPUP_DESTINATION_USER = 'xxxx'; FAQ & Troubleshooting Getting AUTHFAIL with getcontacts API This means the token you have provided in MESIBO_ACCESS_TOKEN is not generated or validated with your phone number which is required for synchronizing contacts. To generate a token by validating your phone number, make sure you have set isLoginEnabled = true. A login screen will then appear during app start, where you can enter your phone number(Example +91XXXXXXXXXX), get an OTP, and log in. If you do not wish to synchronize contacts, set isContactSync = false and provide a list of local contacts in MESIBO_LOCAL_CONTACTS. I do not wish to use phone login, what should I do? Set isLoginEnabled = false and make sure that you provide a valid MESIBO_ACCESS_TOKEN I do not want to synchronize with my phone contacts, how do I configure that? If you do not wish to synchronize contacts, set isContactSync = false and provide a list of local contacts in MESIBO_LOCAL_CONTACTS. Do I need to log in with my phone number every time I load the app? No the first time you log in with your phone number with a valid OTP the token will be stored in localStorage. In future loading of the app, the token will be loaded from local storage. Or if you have provided a valid MESIBO_ACCESS_TOKEN in config.js that will be loaded. Getting $scope.mesibo.X is not a function Ensure that you perform a hard reload so that you have the latest Mesibo Javascript API Install Mesibo Javascript SDK The easiest way to install Mesibo Javascript SDK is to include following in <HEAD> section of your HTML file:<script type="text/javascript" src="https://api.mesibo.com/mesibo.js"></script> You can also use async and defer attributes inside script tag if requires. Alternatively, you may also use DOM method to load the mesibo JS on demand when it is not possible to use the script tag. const script = document.createElement("script"); script.src = "https://api.mesibo.com/mesibo.js"; document.body.appendChild(script); You must use a secure website (https) to use mesibo javascript. It may NOT work from http:// or file:// sites due to browser security restrictions. Notes when using it for Calls and Conferencing Due to the browser security model, camera and microphone access require the following: You MUST use a secure URL ( https://). The http:// or file:// URLs will NOT work. You MUST also use a valid certificate with recognized authority, the self-signed certificate will NOT work. The browser will not grant the camera and microphone permissions unless your app meets the above requirements. If permissions are not granted, calls and conferencing will not work. These restrictions are by the browsers and NOT by the mesibo. Refer Security section in the Mozilla documentation for more information. That's All! You can now begin developing features with mesibo. javascript chat sdk, messaging sdk for javascript, javascript sdk for chat, install sdk through javascript
    https://bgoonz-blog.netlify.app/images/zumzi-video-chat-0aba1c15.png
  • Typography
    Other Websites Here are some other websites I have worked on since endeavoring to learn web development! Alternate Blog Games Projects Wordpress Site Interview Speach Recognition api The Algos Bgoonz Branch
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Jupyter Notebooks Open Binder Jupyter Notebook Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Clock World Clock(Click To See Localized Time)
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Callstack Visualizer See the Pen Linear vs Binary Search by Bryan C Guner (@bgoonz) on CodePen. See the Pen Data Structures Viz by Bryan C Guner (@bgoonz) on CodePen. Callstack Visualizer About the Call Stack TL;DR *The Call Stack tracks function calls. It is a LIFO stack of frames. Each frame represents a function call.* The Call Stack is a fundamental part of the JavaScript language. It is a record-keeping structure that allows us to perform function calls. Each function call is represented as a frame on the Call Stack. This is how the JavaScript engine keeps track of which functions have been called and in what order. The JS engine uses this information to ensure execution picks back up in the right spot after a function returns. When a JavaScript program first starts executing, the Call Stack is empty. When the first function call is made, a new frame is pushed onto the top of the Call Stack. When that function returns, its frame is popped off of the Call Stack. About the Event Loop TL;DR *The Event Loop processes Tasks and Microtasks. It places them into the Call Stack for execution one at a time. It also controls when rerendering occurs.* The Event Loop is a looping algorithm that processes the Tasks/Microtasks in the Task Queue and Microtask Queue. It handles selecting the next Task/Microtask to be run and placing it in the Call Stack for execution. The Event Loop algorithm consists of four key steps: Evaluate Script: Synchronously execute the script as though it were a function body. Run until the Call Stack is empty. Run a Task: Select the oldest Task from the Task Queue. Run it until the Call Stack is empty. Run all Microtasks: Select the oldest Microtask from the Microtask Queue. Run it until the Call Stack is empty. Repeat until the Microtask Queue is empty. Rerender the UI: Rerender the UI. Then, return to step 2. (This step only applies to browsers, not NodeJS). Let's model the Event Loop with some JavaScript psuedocode: while (EventLoop.waitForTask()) { const taskQueue = EventLoop.selectTaskQueue(); if (taskQueue.hasNextTask()) { taskQueue.processNextTask(); } const microtaskQueue = EventLoop.microTaskQueue; while (microtaskQueue.hasNextMicrotask()) { microtaskQueue.processNextMicrotask(); } rerender(); }
    https://bgoonz-blog.netlify.app/images/code.png
  • Gatsby Plugins For This Sites Content Model
    Plug-ins Note: These are the gatsby plugins that power the file system of this website! See more in the Docs section. Code: Gatsby Source File System js const path = require('path'); const fs = require('fs'); const { createFilePath } = require('gatsby-source-filesystem'); const _ = require('lodash'); function findFileNode({ node, getNode }) { let fileNode = node; let ids = [fileNode.id]; while (fileNode && fileNode.internal.type !== `File` && fileNode.parent) { fileNode = getNode(fileNode.parent); if (!fileNode) { break; } if (_.includes(ids, fileNode.id)) { console.log(`found cyclic reference between nodes`); break; } ids.push(fileNode.id); } if (!fileNode || fileNode.internal.type !== `File`) { console.log('did not find ancestor File node'); return null; } return fileNode; } exports.onCreateNode = ({ node, getNode, actions }, options) => { const { createNodeField } = actions; if (node.internal.type === 'MarkdownRemark') { let fileNode = findFileNode({ node, getNode }); if (!fileNode) { throw new Error('could not find parent File node for MarkdownRemark node: ' + node); } let url; if (node.frontmatter.url) { url = node.frontmatter.url; } else if (_.get(options, 'uglyUrls', false)) { url = path.join(fileNode.relativeDirectory, fileNode.name + '.html'); } else { url = createFilePath({ node, getNode }); } createNodeField({ node, name: 'url', value: url }); createNodeField({ node, name: 'absolutePath', value: fileNode.absolutePath }); createNodeField({ node, name: 'relativePath', value: fileNode.relativePath }); createNodeField({ node, name: 'absoluteDir', value: fileNode.dir }); createNodeField({ node, name: 'relativeDir', value: fileNode.relativeDirectory }); createNodeField({ node, name: 'base', value: fileNode.base }); createNodeField({ node, name: 'ext', value: fileNode.ext }); createNodeField({ node, name: 'name', value: fileNode.name }); } }; exports.createPages = ({ graphql, getNode, actions, getNodesByType }) => { const { createPage, deletePage } = actions; // Use GraphQL to bring only the "id" and "html" (added by gatsby-transformer-remark) // properties of the MarkdownRemark nodes. Don't bring additional fields // such as "relativePath". Otherwise, Gatsby's GraphQL resolvers might infer // types these fields as File and change their structure. For example, the // "html" attribute exists only on a GraphQL node, but does not exist on the // underlying node. return graphql(` { allMarkdownRemark { edges { node { id html } } } } `).then((result) => { if (result.errors) { return Promise.reject(result.errors); } const nodes = result.data.allMarkdownRemark.edges.map(({ node }) => node); const siteNode = getNode('Site'); const siteDataNode = getNode('SiteData'); const sitePageNodes = getNodesByType('SitePage'); const sitePageNodesByPath = _.keyBy(sitePageNodes, 'path'); const siteData = _.get(siteDataNode, 'data', {}); const pages = nodes.map((graphQLNode) => { // Use the node id to get the underlying node. It is not exactly the // same node returned by GraphQL, because GraphQL resolvers might // transform node fields. const node = getNode(graphQLNode.id); return { url: node.fields.url, relativePath: node.fields.relativePath, relativeDir: node.fields.relativeDir, base: node.fields.base, name: node.fields.name, frontmatter: node.frontmatter, html: graphQLNode.html }; }); nodes.forEach((graphQLNode) => { const node = getNode(graphQLNode.id); const url = node.fields.url; const template = node.frontmatter.template; if (!template) { console.error(`Error: undefined template for ${url}`); return; } const component = path.resolve(`./src/templates/${template}.js`); if (!fs.existsSync(component)) { console.error(`Error: component "src/templates/${template}.js" missing for ${url}`); return; } const existingPageNode = _.get(sitePageNodesByPath, url); const page = { path: url, component: component, context: { url: url, relativePath: node.fields.relativePath, relativeDir: node.fields.relativeDir, base: node.fields.base, name: node.fields.name, frontmatter: node.frontmatter, html: graphQLNode.html, pages: pages, site: { siteMetadata: _.get(siteData, 'site-metadata', {}), pathPrefix: siteNode.pathPrefix, data: _.omit(siteData, 'site-metadata') } } }; if (existingPageNode && !_.get(page, 'context.menus')) { page.context.menus = _.get(existingPageNode, 'context.menus'); } createPage(page); }); }); }; ``` </pre> Gatsby Source Data<pre> ```javascript const path = require('path'); const yaml = require('js-yaml'); const fse = require('fs-extra'); const chokidar = require('chokidar'); const _ = require('lodash'); const metadataFileName = 'site-metadata.json'; const parsers = { yaml: (data) => yaml.safeLoad(data, { schema: yaml.JSON_SCHEMA }), json: (data) => JSON.parse(data) }; const supportedExtensions = { yaml: parsers.yaml, yml: parsers.yaml, json: parsers.json }; exports.sourceNodes = (props, pluginOptions = {}) => { const createContentDigest = props.createContentDigest; const { createNode } = props.actions; const reporter = props.reporter; if (!_.get(pluginOptions, 'path')) { pluginOptions.path = 'src/data'; } if (!path.isAbsolute(pluginOptions.path)) { pluginOptions.path = path.resolve(process.cwd(), pluginOptions.path); } reporter.info(`[gatsby-source-data] setup file watcher and create site data`); const dataPath = pluginOptions.path; const createSiteDataFromFilesPartial = _.partial(createSiteDataFromFiles, { dataPath, createNode, createContentDigest, reporter }); const watcher = chokidar.watch([dataPath, metadataFileName], { cwd: '.', ignoreInitial: true }); watcher.on('add', createSiteDataFromFilesPartial); watcher.on('change', createSiteDataFromFilesPartial); watcher.on('unlink', createSiteDataFromFilesPartial); return createSiteDataFromFiles({ dataPath, createNode, createContentDigest, reporter }, null); }; async function createSiteDataFromFiles({ dataPath, createNode, createContentDigest, reporter }, changedFile) { reporter.info(`[gatsby-source-data] create site data from files, updated path: ${changedFile}`); let dataFiles = []; const dataPathExists = await fse.pathExists(dataPath); if (dataPathExists) { dataFiles = await readDirRecursively(dataPath); } const metadataPath = path.resolve(metadataFileName); const metadataExists = await fse.pathExists(metadataPath); if (metadataExists) { dataFiles.push(metadataFileName); } const sortedDataFiles = dataFiles.slice().sort(); const data = await convertDataFilesToJSON(sortedDataFiles, dataPath, reporter); createNode({ id: 'SiteData', parent: null, children: [], data: data, internal: { type: 'SiteData', contentDigest: createContentDigest(JSON.stringify(data)), description: `Site data from ${path.relative(process.cwd(), dataPath)}` } }); } async function readDirRecursively(dir, options) { const rootDir = _.get(options, 'rootDir', dir); const files = await fse.readdir(dir); const promises = _.map(files, async (file) => { const filePath = path.join(dir, file); const stats = await fse.stat(filePath); if (stats.isDirectory()) { return readDirRecursively(filePath, { rootDir }); } else if (stats.isFile()) { return path.relative(rootDir, filePath); } else { return null; } }); const recFiles = await Promise.all(promises); return _.chain(recFiles).compact().flatten().value(); } function convertDataFilesToJSON(dataFiles, dataDirPath, reporter) { let promises = _.map(dataFiles, (filePath) => { const pathObject = path.parse(filePath); const absFilePath = pathObject.base === metadataFileName ? metadataFileName : path.join(dataDirPath, filePath); const relPath = pathObject.base === metadataFileName ? metadataFileName : filePath; const relDir = pathObject.base === metadataFileName ? '' : pathObject.dir; const ext = pathObject.ext.substring(1); if (!_.has(supportedExtensions, ext)) { return null; } return fse.readFile(absFilePath).then((data) => { const propPath = _.compact(relDir.split(path.sep).concat(pathObject.name)); const res = {}; try { const parsedData = supportedExtensions[ext](data); _.set(res, propPath, parsedData); } catch (err) { reporter.warn(`[gatsby-source-data] could not parse file: ${relPath}`); } return res; }); }); return Promise.all(promises).then((results) => { return _.reduce(results, (data, res) => _.merge(data, res), {}); }); } </pre>
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Contact! Calendar:
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Sitemap✅HOME🌍✅blog/🌍✅blog/awesome-graphql/🌍✅blog/big-o-complexity/🌍✅blog/blog-archive/🌍✅blog/blogwcomments/🌍✅blog/data-structures/🌍✅blog/git-gateway/🌍✅blog/interview-questions-js/🌍✅blog/my-medium/🌍✅blog/netlify-cms/🌍✅blog/platform-docs/🌍✅blog/python-for-js-dev/🌍✅blog/python-resources/🌍✅blog/web-dev-trends/🌍✅blog/web-scraping/🌍✅⇒🌍✅⇒about/🌍✅⇒about/eng-portfolio/🌍✅⇒about/intrests/🌍✅⇒about/job-search/🌍✅⇒about/resume/🌍✅⇒articles/🌍✅⇒articles/basic-web-dev/🌍✅⇒articles/buffers/🌍✅⇒articles/dev-dep/🌍✅⇒articles/event-loop/🌍✅⇒articles/fs-module/🌍✅⇒articles/how-the-web-works/🌍✅⇒articles/http/🌍✅⇒articles/install/🌍✅⇒articles/intro/🌍✅⇒articles/module-exports/🌍✅⇒articles/node-api-express/🌍✅⇒articles/node-cli-args/🌍✅⇒articles/node-common-modules/🌍✅⇒articles/node-env-variables/🌍✅⇒articles/node-js-language/🌍✅⇒articles/node-package-manager/🌍✅⇒articles/node-repl/🌍✅⇒articles/node-run-cli/🌍✅⇒articles/nodejs/🌍✅⇒articles/nodevsbrowser/🌍✅⇒articles/npm/🌍✅⇒articles/npx/🌍✅⇒articles/os-module/🌍✅⇒articles/reading-files/🌍✅⇒articles/semantic-html/🌍✅⇒articles/semantic/🌍✅⇒articles/the-uniform-resource-locator-(url)/🌍✅⇒articles/understanding-firebase/🌍✅⇒articles/v8/🌍✅⇒articles/web-standards-checklist/🌍✅⇒articles/webdev-tools/🌍✅⇒articles/writing-files/🌍✅⇒audio/🌍✅⇒audio/dfft/🌍✅⇒audio/discrete-fft/🌍✅⇒audio/dtw-python-explained/🌍✅⇒audio/dynamic-time-warping/🌍✅⇒community/🌍✅⇒community/video-chat/🌍✅⇒content/🌍✅⇒content/algo/🌍✅⇒content/archive/🌍✅⇒content/data-structures-algo/🌍✅⇒content/gatsby-queries-mutations/🌍✅⇒content/history-api/🌍✅⇒content/js-async-n-callbacks/🌍✅⇒content/projects/🌍✅⇒content/recent-projects/🌍✅⇒content/trouble-shooting/🌍✅⇒docs/🌍✅⇒docs/appendix/🌍✅⇒docs/await-keyword/🌍✅⇒docs/bash/🌍✅⇒docs/content/🌍✅⇒docs/css/🌍✅⇒docs/data-structures-docs/🌍✅⇒docs/git-repos/🌍✅⇒docs/no-whiteboarding/🌍✅⇒docs/regex-in-js/🌍✅⇒docs/sitemap/🌍✅⇒faq/🌍✅⇒faq/contact/🌍✅⇒faq/plug-ins/🌍✅⇒gallery/🌍✅⇒interact/🌍✅⇒interact/callstack-visual/🌍✅⇒interact/clock/🌍✅⇒interact/jupyter-notebooks/🌍✅⇒interact/other-sites/🌍✅⇒interact/video-chat/🌍✅⇒javascript/🌍✅⇒javascript/bigo/🌍✅⇒javascript/constructor-functions/🌍✅⇒medium/🌍✅⇒medium/medium-links/🌍✅⇒medium/my-websites/🌍✅⇒python/🌍✅⇒python/at-length/🌍✅⇒python/google-sheets-api/🌍✅⇒python/python-ds/🌍✅⇒python/snippets/🌍✅⇒quick-reference/🌍✅⇒quick-reference/awesome-lists/🌍✅⇒quick-reference/awesome-static/🌍✅⇒quick-reference/create-react-app/🌍✅⇒quick-reference/emmet/🌍✅⇒quick-reference/git-bash/🌍✅⇒quick-reference/github-search/🌍✅⇒quick-reference/google-firebase/🌍✅⇒quick-reference/heroku-error-codes/🌍✅⇒quick-reference/installation/🌍✅⇒quick-reference/minifiction/🌍✅⇒quick-reference/new-repo-instructions/🌍✅⇒quick-reference/notes-template/🌍✅⇒quick-reference/psql-setup/🌍✅⇒quick-reference/psql/🌍✅⇒quick-reference/pull-request-rubric/🌍✅⇒quick-reference/quick-links/🌍✅⇒quick-reference/resources/🌍✅⇒quick-reference/toprepos/🌍✅⇒quick-reference/understanding-path/🌍✅⇒quick-reference/vscode-themes/🌍✅⇒quick-reference/vscode/🌍✅⇒react/🌍✅⇒react/createreactapp/🌍✅⇒react/react-docs/🌍✅⇒react/react-in-depth/🌍✅⇒react/react2/🌍✅⇒sitemap/🌍✅⇒tools/🌍✅⇒tools/cloudstorage/🌍✅⇒tools/data-structures/🌍✅⇒tools/dev-utilities/🌍✅⇒tools/markdown-html/🌍✅⇒tools/more-tools/🌍✅review/🌍[✅showcase/🌍] https://bgoonz-blog.netlify.app/showcase/)🌍⇒https://bgoonz-blog.netlify.app/🗺️🌍⇒blog🗺️🌍⇒docs🗺️🌍⇒readme🗺️🌍⇒review🗺️🌍⇒showcase🗺️🌍⇒blog/awesome-graphql🗺️🌍⇒blog/big-o-complexity🗺️🌍⇒blog/blog-archive🗺️🌍⇒blog/blogwcomments🗺️🌍⇒blog/data-structures🗺️🌍⇒blog/flow-control-in-python🗺️🌍⇒blog/functions-in-python🗺️🌍⇒blog/git-gateway🗺️🌍⇒blog/interview-questions-js🗺️🌍⇒blog/media-queries-explained🗺️🌍⇒blog/my-medium🗺️🌍⇒blog/netlify-cms🗺️🌍⇒blog/platform-docs🗺️🌍⇒blog/python-for-js-dev🗺️🌍⇒blog/python-resources🗺️🌍⇒blog/web-dev-trends🗺️🌍⇒blog/web-scraping🗺️🌍⇒docs/about🗺️🌍⇒docs/articles🗺️🌍⇒docs/audio🗺️🌍⇒docs/career🗺️🌍⇒docs/community🗺️🌍⇒docs/content🗺️🌍⇒docs/docs🗺️🌍⇒docs/faq🗺️🌍⇒docs/gallery🗺️🌍⇒docs/interact🗺️🌍⇒docs/javascript🗺️🌍⇒docs/leetcode🗺️🌍⇒docs/other-content🗺️🌍⇒docs/privacy-policy🗺️🌍⇒docs/projects🗺️🌍⇒docs/python🗺️🌍⇒docs/quick-reference🗺️🌍⇒docs/react🗺️🌍⇒docs/reference🗺️🌍⇒docs/search🗺️🌍⇒docs/sitemap🗺️🌍⇒docs/tools🗺️🌍⇒docs/tutorials🗺️🌍⇒docs/about/eng-portfolio🗺️🌍⇒docs/about/ideas-for-this-website🗺️🌍⇒docs/about/intrests🗺️🌍⇒docs/about/job-search🗺️🌍⇒docs/about/resume🗺️🌍⇒docs/articles/basic-web-dev🗺️🌍⇒docs/articles/buffers🗺️🌍⇒docs/articles/dev-dep🗺️🌍⇒docs/articles/event-loop🗺️🌍⇒docs/articles/fs-module🗺️🌍⇒docs/articles/how-the-web-works🗺️🌍⇒docs/articles/http🗺️🌍⇒docs/articles/install🗺️🌍⇒docs/articles/intro🗺️🌍⇒docs/articles/media-queries-no-more🗺️🌍⇒docs/articles/module-exports🗺️🌍⇒docs/articles/nextjs🗺️🌍⇒docs/articles/node-api-express🗺️🌍⇒docs/articles/node-cli-args🗺️🌍⇒docs/articles/node-common-modules🗺️🌍⇒docs/articles/node-env-variables🗺️🌍⇒docs/articles/node-js-language🗺️🌍⇒docs/articles/node-package-manager🗺️🌍⇒docs/articles/node-repl🗺️🌍⇒docs/articles/node-run-cli🗺️🌍⇒docs/articles/nodejs🗺️🌍⇒docs/articles/nodevsbrowser🗺️🌍⇒docs/articles/npm🗺️🌍⇒docs/articles/npx🗺️🌍⇒docs/articles/os-module🗺️🌍⇒docs/articles/package-lock🗺️🌍⇒docs/articles/reading-files🗺️🌍⇒docs/articles/semantic🗺️🌍⇒docs/articles/semantic-html🗺️🌍⇒docs/articles/the-uniform-resource-locator-(url)🗺️🌍⇒docs/articles/understanding-firebase🗺️🌍⇒docs/articles/v8🗺️🌍⇒docs/articles/web-standards-checklist🗺️🌍⇒docs/articles/webdev-tools🗺️🌍⇒docs/articles/write-2-json-with-python🗺️🌍⇒docs/articles/writing-files🗺️🌍⇒docs/audio/audio🗺️🌍⇒docs/audio/audio-feature-extraction🗺️🌍⇒docs/audio/dfft🗺️🌍⇒docs/audio/discrete-fft🗺️🌍⇒docs/audio/dtw-python-explained🗺️🌍⇒docs/audio/dynamic-time-warping🗺️🌍⇒docs/audio/web-audio-api🗺️🌍⇒docs/career/confidence🗺️🌍⇒docs/career/dev-interview🗺️🌍⇒docs/career/interview-dos-n-donts🗺️🌍⇒docs/career/job-boards🗺️🌍⇒docs/community/an-open-letter-2-future-developers🗺️🌍⇒docs/community/video-chat🗺️🌍⇒docs/content/algo🗺️🌍⇒docs/content/archive🗺️🌍⇒docs/content/data-structures-algo🗺️🌍⇒docs/content/gatsby-Queries-Mutations🗺️🌍⇒docs/content/history-api🗺️🌍⇒docs/content/projects🗺️🌍⇒docs/content/recent-projects🗺️🌍⇒docs/content/trouble-shooting🗺️🌍⇒docs/docs/appendix🗺️🌍⇒docs/docs/bash🗺️🌍⇒docs/docs/content🗺️🌍⇒docs/docs/css🗺️🌍⇒docs/docs/data-structures-docs🗺️🌍⇒docs/docs/git-reference🗺️🌍⇒docs/docs/git-repos🗺️🌍⇒docs/docs/html-spec🗺️🌍⇒docs/docs/markdown🗺️🌍⇒docs/docs/no-whiteboarding🗺️🌍⇒docs/docs/node-docs-complete🗺️🌍⇒docs/docs/node-docs-full🗺️🌍⇒docs/docs/regex-in-js🗺️🌍⇒docs/docs/sitemap🗺️🌍⇒docs/faq/contact🗺️🌍⇒docs/faq/plug-ins🗺️🌍⇒docs/interact/callstack-visual🗺️🌍⇒docs/interact/clock🗺️🌍⇒docs/interact/jupyter-notebooks🗺️🌍⇒docs/interact/other-sites🗺️🌍⇒docs/interact/video-chat🗺️🌍⇒docs/javascript/arrow-functions🗺️🌍⇒docs/javascript/await-keyword🗺️🌍⇒docs/javascript/bigo🗺️🌍⇒docs/javascript/clean-code🗺️🌍⇒docs/javascript/constructor-functions🗺️🌍⇒docs/javascript/promises🗺️🌍⇒docs/javascript/review🗺️🌍⇒docs/javascript/this-is-about-this🗺️🌍⇒docs/projects/medium-links🗺️🌍⇒docs/projects/my-websites🗺️🌍⇒docs/python/at-length🗺️🌍⇒docs/python/basics🗺️🌍⇒docs/python/cheat-sheet🗺️🌍⇒docs/python/comprehensive-guide🗺️🌍⇒docs/python/examples🗺️🌍⇒docs/python/flow-control🗺️🌍⇒docs/python/functions🗺️🌍⇒docs/python/google-sheets-api🗺️🌍⇒docs/python/intro-for-js-devs🗺️🌍⇒docs/python/python-ds🗺️🌍⇒docs/python/snippets🗺️🌍⇒docs/quick-reference/Emmet🗺️🌍⇒docs/quick-reference/all-emojis🗺️🌍⇒docs/quick-reference/create-react-app🗺️🌍⇒docs/quick-reference/git-bash🗺️🌍⇒docs/quick-reference/git-tricks🗺️🌍⇒docs/quick-reference/google-firebase🗺️🌍⇒docs/quick-reference/heroku-error-codes🗺️🌍⇒docs/quick-reference/installation🗺️🌍⇒docs/quick-reference/markdown-dropdowns🗺️🌍⇒docs/quick-reference/minifiction🗺️🌍⇒docs/quick-reference/new-repo-instructions🗺️🌍⇒docs/quick-reference/psql-setup🗺️🌍⇒docs/quick-reference/pull-request-rubric🗺️🌍⇒docs/quick-reference/quick-links🗺️🌍⇒docs/quick-reference/topRepos🗺️🌍⇒docs/quick-reference/understanding-path🗺️🌍⇒docs/quick-reference/vscode-themes🗺️🌍⇒docs/react/cheatsheet🗺️🌍⇒docs/react/createReactApp🗺️🌍⇒docs/react/demo🗺️🌍⇒docs/react/jsx🗺️🌍⇒docs/react/react-docs🗺️🌍⇒docs/react/react-in-depth🗺️🌍⇒docs/react/react2🗺️🌍⇒docs/react/render-elements🗺️🌍⇒docs/reference/awesome-lists🗺️🌍⇒docs/reference/awesome-static🗺️🌍⇒docs/reference/bookmarks🗺️🌍⇒docs/reference/embed-the-web🗺️🌍⇒docs/reference/github-search🗺️🌍⇒docs/reference/how-2-reinstall-npm🗺️🌍⇒docs/reference/how-to-kill-a-process🗺️🌍⇒docs/reference/installing-node🗺️🌍⇒docs/reference/intro-to-nodejs🗺️🌍⇒docs/reference/notes-template🗺️🌍⇒docs/reference/psql🗺️🌍⇒docs/reference/resources🗺️🌍⇒docs/reference/vscode🗺️🌍⇒docs/reference/web-api's🗺️🌍⇒docs/tools/data-structures🗺️🌍⇒docs/tools/dev-utilities🗺️🌍⇒docs/tools/google-cloud🗺️🌍⇒docs/tools/markdown-html🗺️🌍⇒docs/tools/more-tools🗺️🌍⇒docs/tutorials/google-lighthouse-cli🗺️
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Regular Expressions Regular Expressions description: CODEX Regular Expressions### description: Regular expressions are patterns used to match character combinations in strings. In JavaScript, regular expressions are also objects. These patterns are used with the exec() and test() methods of RegExp, and with the match(), matchAll(), replace(), replaceAll(), search(), and split() methods of String. This chapter describes JavaScript regular expressions. Creating a regular expression You construct a regular expression in one of two ways: Using a regular expression literal, which consists of a pattern enclosed between slashes, as follows: let re = /ab+c/; Regular expression literals provide compilation of the regular expression when the script is loaded. If the regular expression remains constant, using this can improve performance. 2. Or calling the constructor function of the RegExp object, as follows: let re = new RegExp('ab+c'); Using the constructor function provides runtime compilation of the regular expression. Use the constructor function when you know the regular expression pattern will be changing, or you don't know the pattern and are getting it from another source, such as user input. Writing a regular expression pattern A regular expression pattern is composed of simple characters, such as /abc/, or a combination of simple and special characters, such as /ab*c/ or /Chapter (\d+)\.\d*/. The last example includes parentheses, which are used as a memory device. The match made with this part of the pattern is remembered for later use. Using simple patterns Simple patterns are constructed of characters for which you want to find a direct match. For example, the pattern /abc/ matches character combinations in strings only when the exact sequence "abc" occurs (all characters together and in that order). Such a match would succeed in the strings "Hi, do you know your abc's?" and "The latest airplane designs evolved from slabcraft." In both cases the match is with the substring "abc". There is no match in the string "Grab crab" because while it contains the substring "ab c", it does not contain the exact substring "abc". Using special characters When the search for a match requires something more than a direct match, such as finding one or more b's, or finding white space, you can include special characters in the pattern. For example, to match a single "a" followed by zero or more "b" s followed by "c", you'd use the pattern /ab*c/: the * after "b" means "0 or more occurrences of the preceding item." In the string "cbbabbbbcdebc", this pattern will match the substring "abbbbc". Assertions** : Assertions include boundaries, which indicate the beginnings and endings of lines and words, and other patterns indicating in some way that a match is possible (including look-ahead, look-behind, and conditional expressions).** Character classes** : Distinguish different types of characters. For example, distinguishing between letters and digits.** Groups and ranges** : Indicate groups and ranges of expression characters.** Quantifiers** : Indicate numbers of characters or expressions to match.** Unicode property escapes** : Distinguish based on unicode character properties, for example, upper- and lower-case letters, math symbols, and punctuation.** If you want to look at all the special characters that can be used in regular expressions in a single table, see the following:### Special characters in regular expressions. Escaping If you need to use any of the special characters literally (actually searching for a "*", for instance), you must escape it by putting a backslash in front of it. For instance, to search for "a" followed by "*" followed by "b", you'd use /a\*b/ --- the backslash "escapes" the "*", making it literal instead of special. Similarly, if you're writing a regular expression literal and need to match a slash ("/"), you need to escape that (otherwise, it terminates the pattern) For instance, to search for the string "/example/" followed by one or more alphabetic characters, you'd use /\/example\/[a-z]+/i--the backslashes before each slash make them literal. To match a literal backslash, you need to escape the backslash. For instance, to match the string "C:\" where "C" can be any letter, you'd use /[A-Z]:\\/--- the first backslash escapes the one after it, so the expression searches for a single literal backslash. If using the RegExp constructor with a string literal, remember that the backslash is an escape in string literals, so to use it in the regular expression, you need to escape it at the string literal level./a\*b/ and new RegExp("a\\*b") create the same expression, which searches for "a" followed by a literal "*" followed by "b". If escape strings are not already part of your pattern you can add them using String.replace: function escapeRegExp(string) { return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string } The "g" after the regular expression is an option or flag that performs a global search, looking in the whole string and returning all matches. Using parentheses Parentheses around any part of the regular expression pattern causes that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use. Using regular expressions in JavaScript Regular expressions are used with the RegExp methods test() and exec() and with the String methods match(), replace(), search(), and split(). Method Descriptions exec() Executes a search for a match in a string. It returns an array of information or null on a mismatch. test() Tests for a match in a string. It returns true or false. match() Returns an array containing all of the matches, including capturing groups, or null if no match is found. matchAll() Returns an iterator containing all of the matches, including capturing groups. search() Tests for a match in a string. It returns the index of the match, or -1 if the search fails. replace() Executes a search for a match in a string, and replaces the matched substring with a replacement substring. replaceAll() Executes a search for all matches in a string, and replaces the matched substrings with a replacement substring. split() Uses a regular expression or a fixed string to break a string into an array of substrings. Methods that use regular expressions When you want to know whether a pattern is found in a string, use the test() or search() methods; for more information (but slower execution) use the exec() or match() methods. If you use exec() or match() and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, RegExp. If the match fails, the exec() method returns null (which coerces to false). In the following example, the script uses the exec() method to find a match in a string. let myRe = /d(b+)d/g; let myArray = myRe.exec('cdbbdbsbz'); If you do not need to access the properties of the regular expression, an alternative way of creating myArray is with this script: let myArray = /d(b+)d/g.exec('cdbbdbsbz'); // similar to "cdbbdbsbz".match(/d(b+)d/g); however, // "cdbbdbsbz".match(/d(b+)d/g) outputs Array [ "dbbd" ], while // /d(b+)d/g.exec('cdbbdbsbz') outputs Array [ 'dbbd', 'bb', index: 1, input: 'cdbbdbsbz' ]. (See different behaviors for further info about the different behaviors.) If you want to construct the regular expression from a string, yet another alternative is this script: let myRe = new RegExp('d(b+)d', 'g'); let myArray = myRe.exec('cdbbdbsbz'); With these scripts, the match succeeds and returns the array and updates the properties shown in the following table. Results of regular expression execution. You can use a regular expression created with an object initializer without assigning it to a letiable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a letiable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script: let myRe = /d(b+)d/g; let myArray = myRe.exec('cdbbdbsbz'); console.log('The value of lastIndex is ' + myRe.lastIndex); // "The value of lastIndex is 5" However, if you have this script: let myArray = /d(b+)d/g.exec('cdbbdbsbz'); console.log('The value of lastIndex is ' + /d(b+)d/g.lastIndex); // "The value of lastIndex is 0" The occurrences of /d(b+)d/g in the two statements are different regular expression objects and hence have different values for their lastIndex property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable.[Advanced searching with flags] Regular expressions have six optional flags that allow for functionality like global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression. Flag Description Corresponding property g Global search. RegExp.prototype.global i Case-insensitive search. RegExp.prototype.ignoreCase m Multi-line search. RegExp.prototype.multiline s Allows . to match newline characters. RegExp.prototype.dotAll u "unicode"; treat a pattern as a sequence of unicode code points. RegExp.prototype.unicode y Perform a "sticky" search that matches starting at the current position in the target string. RegExp.prototype.sticky Regular expression flags To include a flag with the regular expression, use this syntax: let re = /pattern/flags; or let re = new RegExp('pattern', 'flags'); Note that the flags are an integral part of a regular expression. They cannot be added or removed later. For example, re = /\w+\s/g creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string. let re = /\w+\s/g; let str = 'fee fi fo fum'; let myArray = str.match(re); console.log(myArray); // ["fee ", "fi ", "fo "] You could replace the line: let re = /\w+\s/g; with: let re = new RegExp('\\w+\\s', 'g'); and get the same result. The behavior associated with the g flag is different when the .exec() method is used. The roles of "class" and "argument" get reversed: In the case of .match(), the string class (or data type) owns the method and the regular expression is just an argument, while in the case of .exec(), it is the regular expression that owns the method, with the string being the argument. Contrast this str.match(re) versus re.exec(str). The g flag is used with the .exec() method to get iterative progression. let xArray; while(xArray = re.exec(str)) console.log(xArray); // produces: // ["fee ", index: 0, input: "fee fi fo fum"] // ["fi ", index: 4, input: "fee fi fo fum"] // ["fo ", index: 7, input: "fee fi fo fum"] The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string. Using special characters to verify input In the following example, the user is expected to enter a phone number. When the user presses the "Check" button, the script checks the validity of the number. If the number is valid (matches the character sequence specified by the regular expression), the script shows a message thanking the user and confirming the number. If the number is invalid, the script informs the user that the phone number is not valid. Within non-capturing parentheses (?: , the regular expression looks for three numeric characters \d{3} OR | a left parenthesis \( followed by three digits\d{3}, followed by a close parenthesis \), (end non-capturing parenthesis )), followed by one dash, forward slash, or decimal point and when found, remember the character ([-\/\.]), followed by three digits \d{3}, followed by the remembered match of a dash, forward slash, or decimal point \1, followed by four digits \d{4}. The Change event activated when the user presses Enter sets the value of RegExp.input. HTML<p> Enter your phone number (with area code) and then click "Check". <br> The expected format is like ###-###-####. </p> <form action="#"> <input id="phone"> <button onclick="testInfo(document.getElementById('phone'));">Check</button> </form> JavaScript let re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/; function testInfo(phoneInput) { let OK = re.exec(phoneInput.value); if (!OK) { console.error(phoneInput.value + ' isn\'t a phone number with area code!'); } else { console.log('Thanks, your phone number is ' + OK[0]);} } Cheat Sheet#### If you found this guide helpful feel free to checkout my GitHub/gist's where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: a/A-Student-Resources Edit description goofy-euclid-1cd736.netlify.app By Bryan Guner on March 6, 2021. Canonical link Exported from Medium on August 17, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Node Docs How to use the Node.js REPL description: "REPL stands for Read-Evaluate-Print-Loop, and it's a great way to explore the Node.js features in a quick way" The node command is the one we use to run our Node.js scripts: node script.js If we omit the filename, we use it in REPL mode: node Note: REPL also known as Read Evaluate Print Loop is a programming language environment (basically a console window) that takes single expression as user input and returns the result back to the console after execution. If you try it now in your terminal, this is what happens:❯ node > the command stays in idle mode and waits for us to enter something. Tip: if you are unsure how to open your terminal, google "How to open terminal on <your-operating-system>". The REPL is waiting for us to enter some JavaScript code, to be more precise. Start simple and enter> console.log('test') test undefined > The first value, test, is the output we told the console to print, then we get undefined which is the return value of running console.log(). We can now enter a new line of JavaScript. Use the tab to autocomplete The cool thing about the REPL is that it's interactive. As you write your code, if you press the tab key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one. Exploring JavaScript objects Try entering the name of a JavaScript class, like Number, add a dot and press tab. The REPL will print all the properties and methods you can access on that class: Explore global objects You can inspect the globals you have access to by typing global. and pressing tab: The _ special variable If after some code you type _, that is going to print the result of the last operation. Dot commands The REPL has some special commands, all starting with a dot .. They are.help: shows the dot commands help.editor: enables editor mode, to write multiline JavaScript code with ease. Once you are in this mode, enter ctrl-D to run the code you wrote..break: when inputting a multi-line expression, entering the .break command will abort further input. Same as pressing ctrl-C..clear: resets the REPL context to an empty object and clears any multi-line expression currently being input..load: loads a JavaScript file, relative to the current working directory.save: saves all you entered in the REPL session to a file (specify the filename).exit: exits the repl (same as pressing ctrl-C two times) The REPL knows when you are typing a multi-line statement without the need to invoke .editor. For example if you start typing an iteration like this:[1, 2, 3].forEach(num => { and you press enter, the REPL will go to a new line that starts with 3 dots, indicating you can now continue to work on that block.... console.log(num) ... }) If you type .break at the end of a line, the multiline mode will stop and the statement will not be executed. Node.js, accept arguments from the command line description: 'How to accept arguments in a Node.js program passed from the command line' You can pass any number of arguments when invoking a Node.js application using node app.js Arguments can be standalone or have a key and a value. For example: node app.js joe or node app.js name=joe This changes how you will retrieve this value in the Node.js code. The way you retrieve it is using the process object built into Node.js. It exposes an argv property, which is an array that contains all the command line invocation arguments. The first element is the full path of the node command. The second element is the full path of the file being executed. All the additional arguments are present from the third position going forward. You can iterate over all the arguments (including the node path and the file path) using a loop: process.argv.forEach((val, index) => { console.log(`${index}: ${val}`); }); You can get only the additional arguments by creating a new array that excludes the first 2 params: const args = process.argv.slice(2); If you have one argument without an index name, like this: node app.js joe you can access it using const args = process.argv.slice(2); args[0]; In this case: node app.js name=joe args[0] is name=joe, and you need to parse it. The best way to do so is by using the minimist library, which helps dealing with arguments: const args = require('minimist')(process.argv.slice(2)); args['name']; //joe Install the required minimist package using npm (lesson about the package manager comes later on). npm install minimist This time you need to use double dashes before each argument name: node app.js --name=joe Output to the command line using Node.js description: 'How to print to the command line console using Node.js, from the basic console.log to more complex scenarios' Basic output using the console module Node.js provides a console module which provides tons of very useful ways to interact with the command line. It is basically the same as the console object you find in the browser. The most basic and most used method is console.log(), which prints the string you pass to it to the console. If you pass an object, it will render it as a string. You can pass multiple variables to console.log, for example: const x = 'x'; const y = 'y'; console.log(x, y); and Node.js will print both. We can also format pretty phrases by passing variables and a format specifier. For example: console.log('My %s has %d years', 'cat', 2); %s format a variable as a string%d format a variable as a number%i format a variable as its integer part only%o format a variable as an object Example: console.log('%o', Number); Clear the console console.clear() clears the console (the behavior might depend on the console used) Counting elements console.count() is a handy method. Take this code: title="Output to the command line using Node.js" src=" https://stackblitz.com/edit/nodejs-dev-0002-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0002-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> What happens is that console.count() will count the number of times a string is printed, and print the count next to it: You can just count apples and oranges: const oranges = ['orange', 'orange']; const apples = ['just one apple']; oranges.forEach((fruit) => { console.count(fruit); }); apples.forEach((fruit) => { console.count(fruit); }); Reset counting The console.countReset() method resets counter used with console.count(). We will use the apples and orange example to demonstrate this. const oranges = ['orange', 'orange']; const apples = ['just one apple']; oranges.forEach((fruit) => { console.count(fruit); }); apples.forEach((fruit) => { console.count(fruit); }); console.countReset('orange'); oranges.forEach((fruit) => { console.count(fruit); }); Notice how the call to console.countReset('orange') resets the value counter to zero. Print the stack trace There might be cases where it's useful to print the call stack trace of a function, maybe to answer the question how did you reach that part of the code? You can do so using console.trace(): const function2 = () => console.trace(); const function1 = () => function2(); function1(); This will print the stack trace. This is what's printed if we try this in the Node.js REPL: Trace at function2 (repl:1:33) at function1 (repl:1:25) at repl:1:1 at ContextifyScript.Script.runInThisContext (vm.js:44:33) at REPLServer.defaultEval (repl.js:239:29) at bound (domain.js:301:14) at REPLServer.runBound [as eval] (domain.js:314:12) at REPLServer.onLine (repl.js:440:10) at emitOne (events.js:120:20) at REPLServer.emit (events.js:210:7) Calculate the time spent You can easily calculate how much time a function takes to run, using time() and timeEnd() const doSomething = () => console.log('test'); const measureDoingSomething = () => { console.time('doSomething()'); //do something, and measure the time it takes doSomething(); console.timeEnd('doSomething()'); }; measureDoingSomething(); stdout and stderr As we saw console.log is great for printing messages in the Console. This is what's called the standard output, or stdout. console.error prints to the stderr stream. It will not appear in the console, but it will appear in the error log. Color the output You can color the output of your text in the console by using escape sequences. An escape sequence is a set of characters that identifies a color. Example: console.log('\x1b[33m%s\x1b[0m', 'hi!'); You can try that in the Node.js REPL, and it will print hi! in yellow. However, this is the low-level way to do this. The simplest way to go about coloring the console output is by using a library. Chalk is such a library, and in addition to coloring it also helps with other styling facilities, like making text bold, italic or underlined. You install it with npm install chalk, then you can use it: const chalk = require('chalk'); console.log(chalk.yellow('hi!')); Using chalk.yellow is much more convenient than trying to remember the escape codes, and the code is much more readable. Check the project link posted above for more usage examples. Create a progress bar Progress is an awesome package to create a progress bar in the console. Install it using npm install progress This snippet creates a 10-step progress bar, and every 100ms one step is completed. When the bar completes we clear the interval: const ProgressBar = require('progress'); const bar = new ProgressBar(':bar', { total: 10 }); const timer = setInterval(() => { bar.tick(); if (bar.complete) { clearInterval(timer); } }, 100); Accept input from the command line in Node.js description: 'How to make a Node.js CLI program interactive using the built-in readline Node.js module' How to make a Node.js CLI program interactive? Node.js since version 7 provides the readline module to perform exactly this: get input from a readable stream such as the process.stdin stream, which during the execution of a Node.js program is the terminal input, one line at a time. const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); readline.question(`What's your name?`, (name) => { console.log(`Hi ${name}!`); readline.close(); }); This piece of code asks the username, and once the text is entered and the user presses enter, we send a greeting. The question() method shows the first parameter (a question) and waits for the user input. It calls the callback function once enter is pressed. In this callback function, we close the readline interface. readline offers several other methods, and I'll let you check them out on the package documentation linked above. If you need to require a password, it's best not to echo it back, but instead show a * symbol. The simplest way is to use the readline-sync package which is very similar in terms of the API and handles this out of the box. A more complete and abstract solution is provided by the Inquirer.js package. You can install it using npm install inquirer, and then you can replicate the above code like this: const inquirer = require('inquirer'); var questions = [ { type: 'input', name: 'name', message: "What's your name?" } ]; inquirer.prompt(questions).then((answers) => { console.log(`Hi ${answers['name']}!`); }); Inquirer.js lets you do many things like asking multiple choices, having radio buttons, confirmations, and more. It's worth knowing all the alternatives, especially the built-in ones provided by Node.js, but if you plan to take CLI input to the next level, Inquirer.js is an optimal choice. Expose functionality from a Node.js file using exports description: 'How to use the module.exports API to expose data to other files in your application, or to other applications as well' Node.js has a built-in module system. A Node.js file can import functionality exposed by other Node.js files. When you want to import something you use const library = require('./library'); to import the functionality exposed in the library.js file that resides in the current file folder. In this file, functionality must be exposed before it can be imported by other files. Any other object or variable defined in the file by default is private and not exposed to the outer world. This is what the module.exports API offered by the module system allows us to do. When you assign an object or a function as a new exports property, that is the thing that's being exposed, and as such, it can be imported in other parts of your app, or in other apps as well. You can do so in 2 ways. The first is to assign an object to module.exports, which is an object provided out of the box by the module system, and this will make your file export just that object:// car.js const car = { brand: 'Ford', model: 'Fiesta' }; module.exports = car; // index.js const car = require('./car'); The second way is to add the exported object as a property of exports. This way allows you to export multiple objects, functions or data: const car = { brand: 'Ford', model: 'Fiesta' }; exports.car = car; or directly exports.car = { brand: 'Ford', model: 'Fiesta' }; And in the other file, you'll use it by referencing a property of your import: const items = require('./items'); const car = items.car; or const car = require('./items').car; What's the difference between module.exports and exports? The first exposes the object it points to. The latter exposes the properties of the object it points to. An introduction to the npm package manager description: 'A quick guide to npm, the powerful package manager key to the success of Node.js. In January 2017 over 350000 packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything.' Introduction to npm npm is the standard package manager for Node.js. In January 2017 over 350000 packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything. It started as a way to download and manage dependencies of Node.js packages, but it has since become a tool used also in frontend JavaScript. There are many things that npm does. Yarn and pnpm are alternatives to npm cli. You can check them out as well. Downloads npm manages downloads of dependencies of your project. Installing all dependencies If a project has a package.json file, by running npm install it will install everything the project needs, in the node_modules folder, creating it if it's not existing already. Installing a single package You can also install a specific package by running npm install <package-name> Furthermore, since npm 5, this command adds <package-name> to the package.json file dependencies. Before version 5, you needed to add the flag --save. Often you'll see more flags added to this command:--save-dev installs and adds the entry to the package.json file devDependencies--no-save installs but does not add the entry to the package.json file dependencies--save-optional installs and adds the entry to the package.json file optionalDependencies--no-optional will prevent optional dependencies from being installed Shorthands of the flags can also be used:-S: --save-D: --save-dev-O: --save-optional The difference between devDependencies and dependencies is that the former contains development tools, like a testing library, while the latter is bundled with the app in production. As for the optionalDependencies the difference is that build failure of the dependency will not cause installation to fail. But it is your program's responsibility to handle the lack of the dependency. Read more about optional dependencies. Updating packages Updating is also made easy, by running npm update npm will check all packages for a newer version that satisfies your versioning constraints. You can specify a single package to update as well: npm update <package-name> Versioning In addition to plain downloads, npm also manages versioning, so you can specify any specific version of a package, or require a version higher or lower than what you need. Many times you'll find that a library is only compatible with a major release of another library. Or a bug in the latest release of a lib, still unfixed, is causing an issue. Specifying an explicit version of a library also helps to keep everyone on the same exact version of a package, so that the whole team runs the same version until the package.json file is updated. In all those cases, versioning helps a lot, and npm follows the semantic versioning (semver) standard. Running Tasks The package.json file supports a format for specifying command line tasks that can be run by using npm run <task-name> For example:{ "scripts": { "start-dev": "node lib/server-development", "start": "node lib/server-production" } } It's very common to use this feature to run Webpack:{ "scripts": { "watch": "webpack --watch --progress --colors --config webpack.conf.js", "dev": "webpack --progress --colors --config webpack.conf.js", "prod": "NODE_ENV=production webpack -p --config webpack.conf.js" } } So instead of typing those long commands, which are easy to forget or mistype, you can run$ npm run watch $ npm run dev $ npm run prod Where does npm install the packages? description: 'How to find out where npm installs the packages' When you install a package using npm you can perform 2 types of installation: a local install a global install By default, when you type an npm install command, like: npm install lodash the package is installed in the current file tree, under the node_modules subfolder. As this happens, npm also adds the lodash entry in the dependencies property of the package.json file present in the current folder. A global installation is performed using the -g flag: npm install -g lodash When this happens, npm won't install the package under the local folder, but instead, it will use a global location. Where, exactly? The npm root -g command will tell you where that exact location is on your machine. On macOS or Linux this location could be /usr/local/lib/node_modules. On Windows it could be C:\Users\YOU\AppData\Roaming\npm\node_modules If you use nvm to manage Node.js versions, however, that location would differ. I, for example, use nvm and my packages location was shown as /Users/joe/.nvm/versions/node/v8.9.0/lib/node_modules. How to use or execute a package installed using npm description: 'How to include and use in your code a package installed in your node_modules folder' When you install a package into your node_modules folder using npm , or also globally, how do you use it in your Node.js code? Say you install lodash, the popular JavaScript utility library, using npm install lodash This is going to install the package in the local node_modules folder. To use it in your code, you just need to import it into your program using require: const _ = require('lodash'); What if your package is an executable? In this case, it will put the executable file under the node_modules/.bin/ folder. One easy way to demonstrate this is cowsay. The cowsay package provides a command line program that can be executed to make a cow say something (and other animals as well 🦊). When you install the package using npm install cowsay, it will install itself and a few dependencies in the node_modules folder: There is a hidden .bin folder, which contains symbolic links to the cowsay binaries: How do you execute those? You can of course type ./node_modules/.bin/cowsay to run it, and it works, but npx, included in the recent versions of npm (since 5.2), is a much better option. You just run: npx cowsay and npx will find the package location. The package.json guide description: 'The package.json file is a key element in lots of app codebases based on the Node.js ecosystem.' If you work with JavaScript, or you've ever interacted with a JavaScript project, Node.js or a frontend project, you surely met the package.json file. What's that for? What should you know about it, and what are some of the cool things you can do with it? The package.json file is kind of a manifest for your project. It can do a lot of things, completely unrelated. It's a central repository of configuration for tools, for example. It's also where npm and yarn store the names and versions for all the installed packages. The file structure Here's an example package.json file:{} It's empty! There are no fixed requirements of what should be in a package.json file, for an application. The only requirement is that it respects the JSON format, otherwise it cannot be read by programs that try to access its properties programmatically. If you're building a Node.js package that you want to distribute over npm things change radically, and you must have a set of properties that will help other people use it. We'll see more about this later on. This is another package.json:{ "name": "test-project" } It defines a name property, which tells the name of the app, or package, that's contained in the same folder where this file lives. Here's a much more complex example, which was extracted from a sample Vue.js application:{ "name": "test-project", "version": "1.0.0", "description": "A Vue.js project", "main": "src/main.js", "private": true, "scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "test": "npm run unit", "lint": "eslint --ext .js,.vue src test/unit", "build": "node build/build.js" }, "dependencies": { "vue": "^2.5.2" }, "devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1", "babel-eslint": "^8.2.1", "babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-jest": "^21.0.2", "babel-loader": "^7.1.1", "babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", "babel-plugin-transform-runtime": "^6.22.0", "babel-plugin-transform-vue-jsx": "^3.5.0", "babel-preset-env": "^1.3.2", "babel-preset-stage-2": "^6.22.0", "chalk": "^2.0.1", "copy-webpack-plugin": "^4.0.1", "css-loader": "^0.28.0", "eslint": "^4.15.0", "eslint-config-airbnb-base": "^11.3.0", "eslint-friendly-formatter": "^3.0.0", "eslint-import-resolver-webpack": "^0.8.3", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-vue": "^4.0.0", "extract-text-webpack-plugin": "^3.0.0", "file-loader": "^1.1.4", "friendly-errors-webpack-plugin": "^1.6.1", "html-webpack-plugin": "^2.30.1", "jest": "^22.0.4", "jest-serializer-vue": "^0.3.0", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.2.0", "portfinder": "^1.0.13", "postcss-import": "^11.0.0", "postcss-loader": "^2.0.8", "postcss-url": "^7.2.1", "rimraf": "^2.6.0", "semver": "^5.3.0", "shelljs": "^0.7.6", "uglifyjs-webpack-plugin": "^1.1.1", "url-loader": "^0.5.8", "vue-jest": "^1.0.2", "vue-loader": "^13.3.0", "vue-style-loader": "^3.0.1", "vue-template-compiler": "^2.5.2", "webpack": "^3.6.0", "webpack-bundle-analyzer": "^2.9.0", "webpack-dev-server": "^2.9.1", "webpack-merge": "^4.1.0" }, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" }, "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"] } there are lots of things going on here: version indicates the current version name sets the application/package name description is a brief description of the app/package main sets the entry point for the application private if set to true prevents the app/package to be accidentally published on npm scripts defines a set of node scripts you can run dependencies sets a list of npm packages installed as dependencies devDependencies sets a list of npm packages installed as development dependencies engines sets which versions of Node.js this package/app works on browserslist is used to tell which browsers (and their versions) you want to support All those properties are used by either npm or other tools that we can use. Properties breakdown Most of those properties are only used on https://www.npmjs.com/, others by scripts that interact with your code, like npm or others. name Sets the package name. Example:"name": "test-project" The name must be less than 214 characters, must not have spaces, it can only contain lowercase letters, hyphens (-) or underscores ( _). This is because when a package is published on npm, it gets its own URL based on this property. If you published this package publicly on GitHub, a good value for this property is the GitHub repository name. author Lists the package author name Example:{ "author": "Joe <joe@whatever.com> (https://whatever.com)" } Can also be used with this format:{ "author": { "name": "Joe", "email": "joe@whatever.com", "url": "https://whatever.com" } } contributors As well as the author, the project can have one or more contributors. This property is an array that lists them. Example:{ "contributors": ["Joe <joe@whatever.com> (https://whatever.com)"] } Can also be used with this format:{ "contributors": [ { "name": "Joe", "email": "joe@whatever.com", "url": "https://whatever.com" } ] } bugs Links to the package issue tracker, most likely a GitHub issues page Example:{ "bugs": "https://github.com/whatever/package/issues" } homepage Sets the package homepage Example:{ "homepage": "https://whatever.com/package" } version Indicates the current version of the package. Example:"version": "1.0.0" This property follows the semantic versioning (semver) notation for versions, which means the version is always expressed with 3 numbers: x.x.x. The first number is the major version, the second the minor version and the third is the patch version. There is a meaning in these numbers: a release that only fixes bugs is a patch release, a release that introduces backward-compatible changes is a minor release, a major release can have breaking changes. license Indicates the license of the package. Example:"license": "MIT" keywords This property contains an array of keywords that associate with what your package does. Example:"keywords": [ "email", "machine learning", "ai" ] This helps people find your package when navigating similar packages, or when browsing the https://www.npmjs.com/ website. description This property contains a brief description of the package Example:"description": "A package to work with strings" This is especially useful if you decide to publish your package to npm so that people can find out what the package is about. repository This property specifies where this package repository is located. Example:"repository": "github:whatever/testing", Notice the github prefix. There are other popular services baked in:"repository": "gitlab:whatever/testing", "repository": "bitbucket:whatever/testing", You can explicitly set the version control system:"repository": { "type": "git", "url": "https://github.com/whatever/testing.git" } You can use different version control systems:"repository": { "type": "svn", "url": "..." } main Sets the entry point for the package. When you import this package in an application, that's where the application will search for the module exports. Example:"main": "src/main.js" private if set to true prevents the app/package to be accidentally published on npm Example:"private": true scripts Defines a set of node scripts you can run Example:"scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "unit": "jest --config test/unit/jest.conf.js --coverage", "test": "npm run unit", "lint": "eslint --ext .js,.vue src test/unit", "build": "node build/build.js" } These scripts are command line applications. You can run them by calling npm run XXXX or yarn XXXX, where XXXX is the command name. Example: npm run dev. You can use any name you want for a command, and scripts can do literally anything you want. dependencies Sets a list of npm packages installed as dependencies. When you install a package using npm or yarn: npm install <PACKAGENAME> yarn add <PACKAGENAME> that package is automatically inserted in this list. Example:"dependencies": { "vue": "^2.5.2" } devDependencies Sets a list of npm packages installed as development dependencies. They differ from dependencies because they are meant to be installed only on a development machine, not needed to run the code in production. When you install a package using npm or yarn: npm install --save-dev <PACKAGENAME> yarn add --dev <PACKAGENAME> that package is automatically inserted in this list. Example:"devDependencies": { "autoprefixer": "^7.1.2", "babel-core": "^6.22.1" } engines Sets which versions of Node.js and other commands this package/app work on Example:"engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0", "yarn": "^0.13.0" } browserslist Is used to tell which browsers (and their versions) you want to support. It's referenced by Babel, Autoprefixer, and other tools, to only add the polyfills and fallbacks needed to the browsers you target. Example:"browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] This configuration means you want to support the last 2 major versions of all browsers with at least 1% of usage (from the CanIUse.com stats), except IE8 and lower.( see more) Command-specific properties The package.json file can also host command-specific configuration, for example for Babel, ESLint, and more. Each has a specific property, like eslintConfig, babel and others. Those are command-specific, and you can find how to use those in the respective command/project documentation. Package versions You have seen in the description above version numbers like these: ~3.0.0 or ^0.13.0. What do they mean, and which other version specifiers can you use? That symbol specifies which updates your package accepts, from that dependency. Given that using semver (semantic versioning) all versions have 3 digits, the first being the major release, the second the minor release and the third is the patch release, you have these " Rules". You can combine most of the versions in ranges, like this: 1.0.0 || >=1.1.0 <1.2.0, to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0. The package-lock.json file description: "The package-lock.json file is automatically generated when installing node packages. Learn what it's about" In version 5, npm introduced the package-lock.json file. What's that? You probably know about the package.json file, which is much more common and has been around for much longer. The goal of package-lock.json file is to keep track of the exact version of every package that is installed so that a product is 100% reproducible in the same way even if packages are updated by their maintainers. This solves a very specific problem that package.json left unsolved. In package.json you can set which versions you want to upgrade to (patch or minor), using the semver notation, for example: if you write ~0.13.0, you want to only update patch releases: 0.13.1 is ok, but 0.14.0 is not. if you write ^0.13.0, you want to get updates that do not change the leftmost non-zero number: 0.13.1, 0.13.2 and so on. If you write ^1.13.0, you will get patch and minor releases: 1.13.1, 1.14.0 and so on up to 2.0.0 but not 2.0.0. if you write 0.13.0, that is the exact version that will be used, always You don't commit to Git your node_modules folder, which is generally huge, and when you try to replicate the project on another machine by using the npm install command, if you specified the ~ syntax and a patch release of a package has been released, that one is going to be installed. Same for ^ and minor releases. If you specify exact versions, like 0.13.0 in the example, you are not affected by this problem. It could be you, or another person trying to initialize the project on the other side of the world by running npm install. So your original project and the newly initialized project are actually different. Even if a patch or minor release should not introduce breaking changes, we all know bugs can (and so, they will) slide in. The package-lock.json sets your currently installed version of each package in stone, and npm will use those exact versions when running npm ci. This concept is not new, and other programming languages package managers (like Composer in PHP) use a similar system for years. The package-lock.json file needs to be committed to your Git repository, so it can be fetched by other people, if the project is public or you have collaborators, or if you use Git as a source for deployments. The dependencies versions will be updated in the package-lock.json file when you run npm update. An example This is an example structure of a package-lock.json file we get when we run npm install cowsay in an empty folder:{ "requires": true, "lockfileVersion": 1, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3. 0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "cowsay": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz" , "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkM Ajufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==", "requires": { "get-stdin": "^5.0.1", "optimist": "~0.6.1", "string-width": "~2.1.1", "strip-eof": "^1.0.0" } }, "get-stdin": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0. 1.tgz", "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/ is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "minimist": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10 .tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" } }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { "ansi-regex": "^3.0.0" } }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" } } } We installed cowsay, which depends on get-stdin optimist string-width strip-eof In turn, those packages require other packages, as we can see from the requires property that some have: ansi-regex is-fullwidth-code-point minimist wordwrap strip-eof They are added in alphabetical order into the file, and each one has a version field, a resolved field that points to the package location, and an integrity string that we can use to verify the package. Computer Networking & Socket Programming Socket programming is the development of programs for Computer Networking. Networking applications are loosely based off of the top most layers of the conceptual 7-layer model called the OSI Model. The layers most relevant to socket programmers is layer 4, the Transport layer, and layer 7, the Application layer. Specific protocols are implemented at each layer, and are instrumental for the functionality of the internet. Node.js exposes extensive API's for implementing these protocols so developers can create socket programming applications. The most common example is the http module. HTTP exists on the Application layer of the OSI Model; if you want to learn more about the http module, read the Node.js http documentation or the Nodejs.dev guide. Another socket programming Node.js module is the dgram module for UDP communication. UDP exists on the Transport layer; for more information about this technology read the Node.js dgram documentaion. More importantly, the net module, which this guide is all about, provides an extensive API for a stream-based TCP server. TCP exists on the Transport layer of the OSI Model and is what HTTP is implemented on top of. TCP is a reliable, ordered, and error-checked delivery of a stream of bytes between applications communicating via an internet protocol (IP) network.~ Wikipedia Net Module - Getting Started The key part of the net module is the net.Socket class. A socket instance in Node.js is both a duplex stream and an event emitter. This means it is readable, writable, and can utilize the event loop. Sockets can be created by the user and by Node.js, and they are the programmatic object for communicating. Sockets must connect to a net.Server class instance; a socket connection to a server is often referred to as a client connection. Every socket connection is considered "private" in the sense that the only entities with access to the connection is the server and the client. A server instance can have multiple client connections, but will maintain separate communication streams with each connection. Lets look at the simplest example of a TCP server, an echo server. An echo server is one which returns the same message sent to it. const net = require('net'); // Create a TCP server using the `net.createServer()` method // The callback method is an event listener for the 'connection' event // This method is passed a single parameter, the client socket connection const server = net.createServer((client) => { console.log('Client connected!'); // The client is a stream, set the data encoding to utf8 client.setEncoding('utf8'); // Manual implementation of an echo server: client.on('data', (data) => { // data is a UTF-8 string console.log(data); // log the message from the client to the server client.write(data); // write the same message back to the client }); // Automatic implementation of an echo server: // client is a stream, use the Stream.pipe prototype method to connect it's // read stream to it's write stream // client.pipe(client) }); // Start the server on localhost:8124 // The `http` module, inherits this method for its own http.Server.listen server.listen(8124, 'localhost', () => { console.log('Waiting for connection...'); }); With this server running, connect to it using your system's command-line TCP interface. The two most common are telnet and netcat. If you're unsure which, try both! If neither work, search on Google for "telnet alternative for <your OS>". In another terminal connect to the running TCP server: telnet localhost 8124 # or nc localhost 8124 If you see the message Client connected! in the TCP server terminal, you can begin sending messages from the client connection terminal. Whatever you send should be sent back to you immediatly (if you copy-and-pasted the code from above directly, you'll receive your message twice because their are two echo implementations). Disconnecting is easy; use your terminal's quit keystroke (commonly CTRL+C) or exit the terminal application instance. Great work! You have succesfully implemented your first TCP server-client connection. Example using net.createConnection() Before starting, open two terminals and startup the Node.js repl (you can also use two files called server.js and client.js respectively). In the following example, we will create a TCP server and a connection to that server using the net module. By doing so, the interactivity is not the same as the previous echo example. In fact, without using other core Node.js modules, this example is completely non-interactive. The client code will disconnect itself at the end of its execution.// In the first repl, create and start a server const net = require('net'); const server = net.createServer((client) => { console.log('Client connected'); // log the client has connected to the server client.setEncoding('utf8'); // set the data encoding client.write('Hello from the server!\n'); // say hello to the new connection client.on('data', (data) => { client.write(data.toUpperCase()); // echo the client message in ALL CAPS }); client.on('end', () => { console.log('Client disconnected'); // log the client has disconnected to the server }); }); server.listen(8124, 'localhost', () => { console.log('Waiting for connection...'); }); // In the second repl, create and connect a client const net = require('net'); const client = net.createConnection(8124, 'localhost', () => { console.log('Connected to Server!'); // log the server connection to the client client.write('Hello from the client!\n'); // say hello to the server }); client.setEncoding('utf8'); // set the encoding client.on('data', (data) => { console.log(data); // log messages from the server to the client client.end(); // end the connection after }); client.on('end', () => { console.log('Disconnected from server'); // log the server disconnection to the client }); The second example introduces an additional event listener 'end'. This is very useful for determining when a socket connection is terminated. In the client code, the call to client.end() is the programatic way of ending a socket connection. Conclusion Fantastic work! With these two examples you should have what you need to get started building your own TCP communication networks. This guide only brushes the surface of socket programming applications, but the most important take away here is that Node.js implements TCP socket connections as duplex streams and event emitters. Understanding those two concepts will benefit your overall understanding of the net module. For more capabilities of the net module read the Node.js net documentation. To learn more, try completing the following challenges: Using readline or stream modules, create an interactive client connection script this can build on the second example provided in this guide Create a group-chat TCP server hint: you can hold multiple client connections in an array use multiple arrays for a multi-channel chat server for an extra challenge try to implement a basic user-store for authentication of user accounts Create a mini CRUD database server using an idiomatic chat-command interface The chat-command interface could use keywords such as create, read, update, and delete so the client can send instructions to the server Data can be persisted between sessions using fs to read and write data to files Find the installed version of an npm package description: 'How to find out which version of a particular package you have installed in your app' To see the version of all installed npm packages, including their dependencies: npm list For example:❯ npm list /Users/joe/dev/node/cowsay └─┬ cowsay@1.3.1 ├── get-stdin@5.0.1 ├─┬ optimist@0.6.1 │ ├── minimist@0.0.10 │ └── wordwrap@0.0.3 ├─┬ string-width@2.1.1 │ ├── is-fullwidth-code-point@2.0.0 │ └─┬ strip-ansi@4.0.0 │ └── ansi-regex@3.0.0 └── strip-eof@1.0.0 You can also just open the package-lock.json file, but this involves some visual scanning. npm list -g is the same, but for globally installed packages. To get only your top-level packages (basically, the ones you told npm to install and you listed in the package.json), run npm list --depth=0:❯ npm list --depth=0 /Users/joe/dev/node/cowsay └── cowsay@1.3.1 You can get the version of a specific package by specifying its name:❯ npm list cowsay /Users/joe/dev/node/cowsay └── cowsay@1.3.1 This also works for dependencies of packages you installed:❯ npm list minimist /Users/joe/dev/node/cowsay └─┬ cowsay@1.3.1 └─┬ optimist@0.6.1 └── minimist@0.0.10 If you want to see what's the latest available version of the package on the npm repository, run npm view [package_name] version:❯ npm view cowsay version 1.3.1 Install an older version of an npm package description: 'Learn how to install an older version of an npm package, something that might be useful to solve a compatibility problem' You can install an old version of an npm package using the @ syntax: npm install <package>@<version> Example: npm install cowsay installs version 1.3.1 (at the time of writing). Install version 1.2.0 with: npm install cowsay@1.2.0 The same can be done with global packages: npm install -g webpack@4.16.4 You might also be interested in listing all the previous versions of a package. You can do it with npm view <package> versions:❯ npm view cowsay versions [ '1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.1.0', '1.1.1', '1.1.2', '1.1.3', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.2.0', '1.2.1', '1.3.0', '1.3.1' ] Update all the Node.js dependencies to their latest version description: 'How do you update all the npm dependencies store in the package.json file, to their latest version available?' When you install a package using npm install <packagename>, the latest available version of the package is downloaded and put in the node_modules folder, and a corresponding entry is added to the package.json and package-lock.json files that are present in your current folder. npm calculates the dependencies and installs the latest available version of those as well. Let's say you install cowsay, a cool command line tool that lets you make a cow say things. When you npm install cowsay, this entry is added to the package.json file:{ "dependencies": { "cowsay": "^1.3.1" } } and this is an extract of package-lock.json, where we removed the nested dependencies for clarity:{ "requires": true, "lockfileVersion": 1, "dependencies": { "cowsay": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/cowsay/-/cowsay-1.3.1.tgz", "integrity": "sha512-3PVFe6FePVtPj1HTeLin9v8WyLl+VmM1l1H/5P+BTTDkMAjufp+0F9eLjzRnOHzVAYeIYFF5po5NjRrgefnRMQ==", "requires": { "get-stdin": "^5.0.1", "optimist": "~0.6.1", "string-width": "~2.1.1", "strip-eof": "^1.0.0" } } } } Now those 2 files tell us that we installed version 1.3.1 of cowsay, and our rule for updates is ^1.3.1, which for the npm versioning rules means that npm can update to patch and minor releases: 1.3.2, 1.4.0 and so on. If there is a new minor or patch release and we type npm update, the installed version is updated, and the package-lock.json file diligently filled with the new version. Since npm version 5.0.0, npm update will update the package.json with the updated version. Use npm update --no-save to not update package.json. To discover new releases of the packages, you run npm outdated. Here's the list of a few outdated packages in one repository that wasn't updated for quite a while: Some of those updates are major releases. Running npm update won't update the version of those. Major releases are never updated in this way because they (by definition) introduce breaking changes, and npm wants to save you trouble. To update all packages to a new major version, install the npm-check-updates package globally: npm install -g npm-check-updates then run it: ncu -u this will upgrade all the version hints in the package.json file, to dependencies and devDependencies, so npm can install the new major version. You are now ready to run the update: npm update If you just downloaded the project without the node_modules dependencies and you want to install the shiny new versions first, just run npm install Semantic Versioning using npm description: 'Semantic Versioning is a convention used to provide a meaning to versions' If there's one great thing in Node.js packages, it's that they all agreed on using Semantic Versioning for their version numbering. The Semantic Versioning concept is simple: all versions have 3 digits: x.y.z. the first digit is the major version the second digit is the minor version the third digit is the patch version When you make a new release, you don't just up a number as you please, but you have rules: you up the major version when you make incompatible API changes you up the minor version when you add functionality in a backward-compatible manner you up the patch version when you make backward-compatible bug fixes The convention is adopted all across programming languages, and it is very important that every npm package adheres to it, because the whole system depends on that. Why is that so important? Because npm set some rules we can use in the package.json file to choose which versions it can update our packages to, when we run npm update. The rules use those symbols:^~>>=<<==-|| Let's see those rules in detail:^: It will only do updates that do not change the leftmost non-zero number i.e there can be changes in minor version or patch version but not in major version. If you write ^13.1.0, when running npm update, it can update to 13.2.0, 13.3.0 even 13.3.1, 13.3.2 and so on, but not to 14.0.0 or above.~: if you write ~0.13.0 when running npm update it can update to patch releases: 0.13.1 is ok, but 0.14.0 is not.>: you accept any version higher than the one you specify>=: you accept any version equal to or higher than the one you specify<=: you accept any version equal or lower to the one you specify<: you accept any version lower than the one you specify=: you accept that exact version-: you accept a range of versions. Example: 2.1.0 - 2.6.2||: you combine sets. Example: < 2.1 || > 2.6 You can combine some of those notations, for example use 1.0.0 || >=1.1.0 <1.2.0 to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0. There are other rules, too: no symbol: you accept only that specific version you specify ( 1.2.1) latest: you want to use the latest version available Uninstalling npm packages description: 'How to uninstall an npm Node.js package, locally or globally' To uninstall a package you have previously installed locally (using npm install <package-name> in the node_modules folder, run npm uninstall <package-name> from the project root folder (the folder that contains the node_modules folder). Using the -S flag, or --save, this operation will also remove the reference in the package.json file. package.json will be automatically updated with devDependency and dependency once you uninstall npm package. If the package is installed globally, you need to add the -g / --global flag: npm uninstall -g <package-name> for example: npm uninstall -g webpack and you can run this command from anywhere you want on your system because the folder where you currently are does not matter. npm global or local packages description: 'When is a package best installed globally? Why?' The main difference between local and global packages is this: local packages are installed in the directory where you run npm install <package-name>, and they are put in the node_modules folder under this directory global packages are all put in a single place in your system (exactly where depends on your setup), regardless of where you run npm install -g <package-name> In your code you can only require local packages: require('package-name'); so when should you install in one way or another? In general, all packages should be installed locally. This makes sure you can have dozens of applications in your computer, all running a different version of each package if needed. Updating a global package would make all your projects use the new release, and as you can imagine this might cause nightmares in terms of maintenance, as some packages might break compatibility with further dependencies, and so on. All projects have their own local version of a package, even if this might appear like a waste of resources, it's minimal compared to the possible negative consequences. A package should be installed globally when it provides an executable command that you run from the shell (CLI), and it's reused across projects. You can also install executable commands locally and run them using npx, but some packages are just better installed globally. Great examples of popular global packages which you might know are npm create-react-app vue-cli grunt-cli mocha react-native-cli gatsby-cli forever nodemon You probably have some packages installed globally already on your system. You can see them by running npm list -g --depth 0 on your command line. npm dependencies and devDependencies description: 'When is a package a dependency, and when is it a dev dependency?' When you install an npm package using npm install <package-name>, you are installing it as a dependency. The package is automatically listed in the package.json file, under the dependencies list (as of npm 5: before you had to manually specify --save). When you add the -D flag, or --save-dev, you are installing it as a development dependency, which adds it to the devDependencies list. Development dependencies are intended as development-only packages, that are unneeded in production. For example testing packages, webpack or Babel. When you go in production, if you type npm install and the folder contains a package.json file, they are installed, as npm assumes this is a development deploy. You need to set the --production flag ( npm install --production) to avoid installing those development dependencies. The npx Node.js Package Runner description: 'npx is a very cool way to run Node.js code, and provides many useful features' npx is a very powerful command that's been available in npm starting version 5.2, released in July 2017. If you don't want to install npm, you can install npx as a standalone package npx lets you run code built with Node.js and published through the npm registry. Easily run local commands Node.js developers used to publish most of the executable commands as global packages, in order for them to be in the path and executable immediately. This was a pain because you could not really install different versions of the same command. Running npx commandname automatically finds the correct reference of the command inside the node_modules folder of a project, without needing to know the exact path, and without requiring the package to be installed globally and in the user's path. Installation-less command execution There is another great feature of npx, which is allowing to run commands without first installing them. This is pretty useful, mostly because: you don't need to install anything you can run different versions of the same command, using the syntax @version A typical demonstration of using npx is through the cowsay command. cowsay will print a cow saying what you wrote in the command. For example: cowsay "Hello" will print _______ < Hello > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || This only works if you have the cowsay command globally installed from npm previously. Otherwise you'll get an error when you try to run the command. npx allows you to run that npm command without installing it first. If the command isn't found, npx will install it into a central cache: npx cowsay "Hello" will do the job. Now, this is a funny useless command. Other scenarios include: running the vue CLI tool to create new applications and run them: npx @vue/cli create my-vue-app creating a new React app using create-react-app: npx create-react-app my-react-app and many more. Run some code using a different Node.js version Use the @ to specify the version, and combine that with the node npm package: npx node@10 -v #v10.18.1 npx node@12 -v #v12.14.1 This helps to avoid tools like nvm or the other Node.js version management tools. Run arbitrary code snippets directly from a URL npx does not limit you to the packages published on the npm registry. You can run code that sits in a GitHub gist, for example: npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32 Of course, you need to be careful when running code that you do not control, as with great power comes great responsibility.'The Node.js Event Loop' description: 'The Event Loop is one of the most important aspects to understand about Node.js' Introduction The Event Loop is one of the most important aspects to understand about Node.js. Why is this so important? Because it explains how Node.js can be asynchronous and have non-blocking I/O, and so it explains basically the "killer app" of Node.js, the thing that made it this successful. The Node.js JavaScript code runs on a single thread. There is just one thing happening at a time. This is a limitation that's actually very helpful, as it simplifies a lot how you program without worrying about concurrency issues. You just need to pay attention to how you write your code and avoid anything that could block the thread, like synchronous network calls or infinite loops. In general, in most browsers there is an event loop for every browser tab, to make every process isolated and avoid a web page with infinite loops or heavy processing to block your entire browser. The environment manages multiple concurrent event loops, to handle API calls for example. Web Workers run in their own event loop as well. You mainly need to be concerned that your code will run on a single event loop, and write code with this thing in mind to avoid blocking it. Blocking the event loop Any JavaScript code that takes too long to return back control to the event loop will block the execution of any JavaScript code in the page, even block the UI thread, and the user cannot click around, scroll the page, and so on. Almost all the I/O primitives in JavaScript are non-blocking. Network requests, filesystem operations, and so on. Being blocking is the exception, and this is why JavaScript is based so much on callbacks, and more recently on promises and async/await. The call stack The call stack is a LIFO (Last In, First Out) stack. The event loop continuously checks the call stack to see if there's any function that needs to run. While doing so, it adds any function call it finds to the call stack and executes each one in order. You know the error stack trace you might be familiar with, in the debugger or in the browser console? The browser looks up the function names in the call stack to inform you which function originates the current call: A simple event loop explanation Let's pick an example: title="A simple event loop explanation" src=" https://stackblitz.com/edit/nodejs-dev-0003-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0003-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> When this code runs, first foo() is called. Inside foo() we first call bar(), then we call baz(). At this point the call stack looks like this: The event loop on every iteration looks if there's something in the call stack, and executes it: until the call stack is empty. Queuing function execution The above example looks normal, there's nothing special about it: JavaScript finds things to execute, runs them in order. Let's see how to defer a function until the stack is clear. The use case of setTimeout(() => {}, 0) is to call a function, but execute it once every other function in the code has executed. Take this example: title="Queuing function execution" src=" https://stackblitz.com/edit/nodejs-dev-0004-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0004-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> This code prints, maybe surprisingly: foo baz bar When this code runs, first foo() is called. Inside foo() we first call setTimeout, passing bar as an argument, and we instruct it to run immediately as fast as it can, passing 0 as the timer. Then we call baz(). At this point the call stack looks like this: Here is the execution order for all the functions in our program: Why is this happening? The Message Queue When setTimeout() is called, the Browser or Node.js starts the timer. Once the timer expires, in this case immediately as we put 0 as the timeout, the callback function is put in the Message Queue. The Message Queue is also where user-initiated events like click or keyboard events, or fetch responses are queued before your code has the opportunity to react to them. Or also DOM events like onload. The loop gives priority to the call stack, and it first processes everything it finds in the call stack, and once there's nothing in there, it goes to pick up things in the message queue. We don't have to wait for functions like setTimeout, fetch or other things to do their own work, because they are provided by the browser, and they live on their own threads. For example, if you set the setTimeout timeout to 2 seconds, you don't have to wait 2 seconds - the wait happens elsewhere. ES6 Job Queue ECMAScript 2015 introduced the concept of the Job Queue, which is used by Promises (also introduced in ES6/ES2015). It's a way to execute the result of an async function as soon as possible, rather than being put at the end of the call stack. Promises that resolve before the current function ends will be executed right after the current function. I find nice the analogy of a rollercoaster ride at an amusement park: the message queue puts you at the back of the queue, behind all the other people, where you will have to wait for your turn, while the job queue is the fastpass ticket that lets you take another ride right after you finished the previous one. Example: title="ECMAScript 2015 Job Queue" src=" https://stackblitz.com/edit/nodejs-dev-0005-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0005-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> That's a big difference between Promises (and Async/await, which is built on promises) and plain old asynchronous functions through setTimeout() or other platform APIs. Finally, here's what the call stack looks like for the example above:'Understanding process.nextTick()' description: 'The Node.js process.nextTick function interacts with the event loop in a special way' As you try to understand the Node.js event loop, one important part of it is process.nextTick(). Every time the event loop takes a full trip, we call it a tick. When we pass a function to process.nextTick(), we instruct the engine to invoke this function at the end of the current operation, before the next event loop tick starts: process.nextTick(() => { //do something }); The event loop is busy processing the current function code. When this operation ends, the JS engine runs all the functions passed to nextTick calls during that operation. It's the way we can tell the JS engine to process a function asynchronously (after the current function), but as soon as possible, not queue it. Calling setTimeout(() => {}, 0) will execute the function at the end of next tick, much later than when using nextTick() which prioritizes the call and executes it just before the beginning of the next tick. Use nextTick() when you want to make sure that in the next event loop iteration that code is already executed. Introduction to Node.js description: "Getting started guide to Node.js, the server-side JavaScript runtime environment. Node.js is built on top of the Google Chrome V8 JavaScript engine, and it's mainly used to create web servers - but it's not limited to just that." Node.js is an open-source and cross-platform JavaScript runtime environment. It is a popular tool for almost any kind of project! Node.js runs the V8 JavaScript engine, the core of Google Chrome, outside of the browser. This allows Node.js to be very performant. A Node.js app runs in a single process, without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm. When Node.js performs an I/O operation, like reading from the network, accessing a database or the filesystem, instead of blocking the thread and wasting CPU cycles waiting, Node.js will resume the operations when the response comes back. This allows Node.js to handle thousands of concurrent connections with a single server without introducing the burden of managing thread concurrency, which could be a significant source of bugs. Node.js has a unique advantage because millions of frontend developers that write JavaScript for the browser are now able to write the server-side code in addition to the client-side code without the need to learn a completely different language. In Node.js the new ECMAScript standards can be used without problems, as you don't have to wait for all your users to update their browsers - you are in charge of deciding which ECMAScript version to use by changing the Node.js version, and you can also enable specific experimental features by running Node.js with flags. A Vast Number of Libraries npm with its simple structure helped the ecosystem of Node.js proliferate, and now the npm registry hosts over 1,000,000 open source packages you can freely use. An Example Node.js Application The most common example Hello World of Node.js is a web server: title="Hello world web server" src=" https://stackblitz.com/edit/nodejs-dev-0001-01?embed=1&file=index.js&zenmode=1" alt="nodejs-dev-0001-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> This code first includes the Node.js http module. Node.js has a fantastic standard library, including first-class support for networking. The createServer() method of http creates a new HTTP server and returns it. The server is set to listen on the specified port and host name. When the server is ready, the callback function is called, in this case informing us that the server is running. Whenever a new request is received, the request event is called, providing two objects: a request (an http.IncomingMessage object) and a response (an http.ServerResponse object). Those 2 objects are essential to handle the HTTP call. The first provides the request details. In this simple example, this is not used, but you could access the request headers and request data. The second is used to return data to the caller. In this case with: res.statusCode = 200; we set the statusCode property to 200, to indicate a successful response. We set the Content-Type header: res.setHeader('Content-Type', 'text/plain'); and we close the response, adding the content as an argument to end(): res.end('Hello World\n'); Node.js Frameworks and Tools Node.js is a low-level platform. In order to make things easy and exciting for developers, thousands of libraries were built upon Node.js by the community. Many of those established over time as popular options. Here is a non-comprehensive list of the ones worth learning: AdonisJS: A TypeScript-based fully featured framework highly focused on developer ergonomics, stability, and confidence. Adonis is one of the fastest Node.js web frameworks. Egg.js: A framework to build better enterprise frameworks and apps with Node.js & Koa. Express: It provides one of the most simple yet powerful ways to create a web server. Its minimalist approach, unopinionated, focused on the core features of a server, is key to its success. Fastify: A web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. Fastify is one of the fastest Node.js web frameworks. FeatherJS: Feathers is a lightweight web-framework for creating real-time applications and REST APIs using JavaScript or TypeScript. Build prototypes in minutes and production-ready apps in days. Gatsby: A React-based, GraphQL powered, static site generator with a very rich ecosystem of plugins and starters. hapi: A rich framework for building applications and services that enables developers to focus on writing reusable application logic instead of spending time building infrastructure. koa: It is built by the same team behind Express, aims to be even simpler and smaller, building on top of years of knowledge. The new project born out of the need to create incompatible changes without disrupting the existing community. Loopback.io: Makes it easy to build modern applications that require complex integrations. Meteor: An incredibly powerful full-stack framework, powering you with an isomorphic approach to building apps with JavaScript, sharing code on the client and the server. Once an off-the-shelf tool that provided everything, now integrates with frontend libs React, Vue, and Angular. Can be used to create mobile apps as well. Micro: It provides a very lightweight server to create asynchronous HTTP microservices. NestJS: A TypeScript based progressive Node.js framework for building enterprise-grade efficient, reliable and scalable server-side applications. Next.js: React framework that gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. Nx: A toolkit for full-stack monorepo development using NestJS, Express, React, Angular, and more! Nx helps scale your development from one team building one application to many teams collaborating on multiple applications! Sapper: Sapper is a framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing. Offers SSR and more! Socket.io: A real-time communication engine to build network applications. Strapi: Strapi is a flexible, open-source Headless CMS that gives developers the freedom to choose their favorite tools and frameworks while also allowing editors to easily manage and distribute their content. By making the admin panel and API extensible through a plugin system, Strapi enables the world's largest companies to accelerate content delivery while building beautiful digital experiences.'Understanding setImmediate()' description: 'The Node.js setImmediate function interacts with the event loop in a special way' When you want to execute some piece of code asynchronously, but as soon as possible, one option is to use the setImmediate() function provided by Node.js: setImmediate(() => { //run something }); Any function passed as the setImmediate() argument is a callback that's executed in the next iteration of the event loop. How is setImmediate() different from setTimeout(() => {}, 0) (passing a 0ms timeout), and from process.nextTick()? A function passed to process.nextTick() is going to be executed on the current iteration of the event loop, after the current operation ends. This means it will always execute before setTimeout and setImmediate. A setTimeout() callback with a 0ms delay is very similar to setImmediate(). The execution order will depend on various factors, but they will be both run in the next iteration of the event loop. Discover JavaScript Timers description: 'When writing JavaScript code, you might want to delay the execution of a function. Learn how to use setTimeout and setInterval to schedule functions in the future' setTimeout() When writing JavaScript code, you might want to delay the execution of a function. This is the job of setTimeout. You specify a callback function to execute later, and a value expressing how later you want it to run, in milliseconds: setTimeout(() => { // runs after 2 seconds }, 2000); setTimeout(() => { // runs after 50 milliseconds }, 50); This syntax defines a new function. You can call whatever other function you want in there, or you can pass an existing function name, and a set of parameters: const myFunction = (firstParam, secondParam) => { // do something }; // runs after 2 seconds setTimeout(myFunction, 2000, firstParam, secondParam); setTimeout returns the timer id. This is generally not used, but you can store this id, and clear it if you want to delete this scheduled function execution: const id = setTimeout(() => { // should run after 2 seconds }, 2000); // I changed my mind clearTimeout(id); Zero delay If you specify the timeout delay to 0, the callback function will be executed as soon as possible, but after the current function execution: setTimeout(() => { console.log('after '); }, 0); console.log(' before '); This code will print before after This is especially useful to avoid blocking the CPU on intensive tasks and let other functions be executed while performing a heavy calculation, by queuing functions in the scheduler. Some browsers (IE and Edge) implement a setImmediate() method that does this same exact functionality, but it's not standard and unavailable on other browsers. But it's a standard function in Node.js. setInterval() setInterval is a function similar to setTimeout, with a difference: instead of running the callback function once, it will run it forever, at the specific time interval you specify (in milliseconds): setInterval(() => { // runs every 2 seconds }, 2000); The function above runs every 2 seconds unless you tell it to stop, using clearInterval, passing it the interval id that setInterval returned: const id = setInterval(() => { // runs every 2 seconds }, 2000); clearInterval(id); It's common to call clearInterval inside the setInterval callback function, to let it auto-determine if it should run again or stop. For example this code runs something unless App.somethingIWait has the value arrived: const interval = setInterval(() => { if (App.somethingIWait === 'arrived') { clearInterval(interval); return; } // otherwise do things }, 100); Recursive setTimeout setInterval starts a function every n milliseconds, without any consideration about when a function finished its execution. If a function always takes the same amount of time, it's all fine: Maybe the function takes different execution times, depending on network conditions for example: And maybe one long execution overlaps the next one: To avoid this, you can schedule a recursive setTimeout to be called when the callback function finishes: const myFunction = () => { // do something setTimeout(myFunction, 1000); }; setTimeout(myFunction, 1000); to achieve this scenario: setTimeout and setInterval are available in Node.js, through the Timers module. Node.js also provides setImmediate(), which is equivalent to using setTimeout(() => {}, 0), mostly used to work with the Node.js Event Loop.'JavaScript Asynchronous Programming and Callbacks' description: 'JavaScript is synchronous by default, and is single threaded. This means that code cannot create new threads and run in parallel. Find out what asynchronous code means and how it looks like' Asynchronicity in Programming Languages Computers are asynchronous by design. Asynchronous means that things can happen independently of the main program flow. In the current consumer computers, every program runs for a specific time slot and then it stops its execution to let another program continue their execution. This thing runs in a cycle so fast that it's impossible to notice. We think our computers run many programs simultaneously, but this is an illusion (except on multiprocessor machines). Programs internally use interrupts, a signal that's emitted to the processor to gain the attention of the system. I won't go into the internals of this, but just keep in mind that it's normal for programs to be asynchronous and halt their execution until they need attention, allowing the computer to execute other things in the meantime. When a program is waiting for a response from the network, it cannot halt the processor until the request finishes. Normally, programming languages are synchronous and some provide a way to manage asynchronicity in the language or through libraries. C, Java, C#, PHP, Go, Ruby, Swift, and Python are all synchronous by default. Some of them handle async by using threads, spawning a new process. JavaScript JavaScript is synchronous by default and is single threaded. This means that code cannot create new threads and run in parallel. Lines of code are executed in series, one after another, for example: const a = 1; const b = 2; const c = a * b; console.log(c); doSomething(); But JavaScript was born inside the browser, its main job, in the beginning, was to respond to user actions, like onClick, onMouseOver, onChange, onSubmit and so on. How could it do this with a synchronous programming model? The answer was in its environment. The browser provides a way to do it by providing a set of APIs that can handle this kind of functionality. More recently, Node.js introduced a non-blocking I/O environment to extend this concept to file access, network calls and so on. Callbacks You can't know when a user is going to click a button. So, you define an event handler for the click event. This event handler accepts a function, which will be called when the event is triggered: document.getElementById('button').addEventListener('click', () => { //item clicked }); This is the so-called callback. A callback is a simple function that's passed as a value to another function, and will only be executed when the event happens. We can do this because JavaScript has first-class functions, which can be assigned to variables and passed around to other functions (called higher-order functions) It's common to wrap all your client code in a load event listener on the window object, which runs the callback function only when the page is ready: window.addEventListener('load', () => { //window loaded //do what you want }); Callbacks are used everywhere, not just in DOM events. One common example is by using timers: setTimeout(() => { // runs after 2 seconds }, 2000); XHR requests also accept a callback, in this example by assigning a function to a property that will be called when a particular event occurs (in this case, the state of the request changes): const xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { xhr.status === 200 ? console.log(xhr.responseText) : console.error('error'); } }; xhr.open('GET', 'https://yoursite.com'); xhr.send(); Handling errors in callbacks How do you handle errors with callbacks? One very common strategy is to use what Node.js adopted: the first parameter in any callback function is the error object: error-first callbacks If there is no error, the object is null. If there is an error, it contains some description of the error and other information. fs.readFile('/file.json', (err, data) => { if (err) { //handle error console.log(err); return; } //no errors, process data console.log(data); }); The problem with callbacks Callbacks are great for simple cases! However every callback adds a level of nesting, and when you have lots of callbacks, the code starts to be complicated very quickly: window.addEventListener('load', () => { document.getElementById('button').addEventListener('click', () => { setTimeout(() => { items.forEach((item) => { //your code here }); }, 2000); }); }); This is just a simple 4-levels code, but I've seen much more levels of nesting and it's not fun. How do we solve this? Alternatives to callbacks Starting with ES6, JavaScript introduced several features that help us with asynchronous code that do not involve using callbacks: Promises (ES6) and Async/Await (ES2017). Understanding JavaScript Promises description: 'Promises are one way to deal with asynchronous code in JavaScript, without writing too many callbacks in your code.' Introduction to promises title="Introduction to promises" src=" https://stackblitz.com/edit/nodejs-dev-0006-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0006-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> A promise is commonly defined as a proxy for a value that will eventually become available. Promises are one way to deal with asynchronous code, without getting stuck in callback hell. Promises have been part of the language for years (standardized and introduced in ES2015), and have recently become more integrated, with async and await in ES2017. Async functions use promises behind the scenes, so understanding how promises work is fundamental to understanding how async and await work. How promises work, in brief Once a promise has been called, it will start in a pending state. This means that the calling function continues executing, while the promise is pending until it resolves, giving the calling function whatever data was being requested. The created promise will eventually end in a resolved state, or in a rejected state, calling the respective callback functions (passed to then and catch) upon finishing. Which JS APIs use promises? In addition to your own code and libraries code, promises are used by standard modern Web APIs such as: the Battery API the Fetch API Service Workers It's unlikely that in modern JavaScript you'll find yourself not using promises, so let's start diving right into them. Creating a promise The Promise API exposes a Promise constructor, which you initialize using new Promise(): let done = true; const isItDoneYet = new Promise((resolve, reject) => { if (done) { const workDone = 'Here is the thing I built'; resolve(workDone); } else { const why = 'Still working on something else'; reject(why); } }); As you can see, the promise checks the done global constant, and if that's true, the promise goes to a resolved state (since the resolve callback was called); otherwise, the reject callback is executed, putting the promise in a rejected state. (If none of these functions is called in the execution path, the promise will remain in a pending state) A more common example you may come across is a technique called Promisifying. This technique is a way to be able to use a classic JavaScript function that takes a callback, and have it return a promise: const fs = require('fs'); const getFile = (fileName) => { return new Promise((resolve, reject) => { fs.readFile(fileName, (err, data) => { if (err) { reject(err); // calling `reject` will cause the promise to fail with or without the error passed as an argument return; // and we don't want to go any further } resolve(data); }); }); }; getFile('/etc/passwd') .then((data) => console.log(data)) .catch((err) => console.error(err)); In recent versions of Node.js, you won't have to do this manual conversion for a lot of the API. There is a promisifying function available in the util module that will do this for you, given that the function you're promisifying has the correct signature. Consuming a promise Now let's see how the promise can be consumed or used. const isItDoneYet = new Promise(/* ... as above ... */); //... const checkIfItsDone = () => { isItDoneYet .then((ok) => { console.log(ok); }) .catch((err) => { console.error(err); }); }; Running checkIfItsDone() will specify functions to execute when the isItDoneYet promise resolves (in the then call) or rejects (in the catch call). Chaining promises A promise can be returned to another promise, creating a chain of promises. A great example of chaining promises is the Fetch API, which we can use to get a resource and queue a chain of promises to execute when the resource is fetched. The Fetch API is a promise-based mechanism, and calling fetch() is equivalent to defining our own promise using new Promise(). Example of chaining promises const status = (response) => { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response); } return Promise.reject(new Error(response.statusText)); }; const json = (response) => response.json(); fetch('/todos.json') .then(status) // note that the `status` function is actually **called** here, and that it **returns a promise*** .then(json) // likewise, the only difference here is that the `json` function here returns a promise that resolves with `data` .then((data) => { // ... which is why `data` shows up here as the first parameter to the anonymous function console.log('Request succeeded with JSON response', data); }) .catch((error) => { console.log('Request failed', error); }); node-fetch is minimal code for window.fetch compatible API on Node.js runtime. In this example, we call fetch() to get a list of TODO items from the todos.json file found in the domain root, and we create a chain of promises. Running fetch() returns a response, which has many properties, and within those we reference: status, a numeric value representing the HTTP status code statusText, a status message, which is OK if the request succeeded response also has a json() method, which returns a promise that will resolve with the content of the body processed and transformed into JSON. So given those promises, this is what happens: the first promise in the chain is a function that we defined, called status(), that checks the response status and if it's not a success response (between 200 and 299), it rejects the promise. This operation will cause the promise chain to skip all the chained promises listed and will skip directly to the catch() statement at the bottom, logging the Request failed text along with the error message. If that succeeds instead, it calls the json() function we defined. Since the previous promise, when successful, returned the response object, we get it as an input to the second promise. In this case, we return the data JSON processed, so the third promise receives the JSON directly:.then((data) => { console.log('Request succeeded with JSON response', data) }) and we simply log it to the console. Handling errors When anything in the chain of promises fails and raises an error or rejects the promise, the control goes to the nearest catch() statement down the chain. new Promise((resolve, reject) => { throw new Error('Error'); }).catch((err) => { console.error(err); }); // or new Promise((resolve, reject) => { reject('Error'); }).catch((err) => { console.error(err); }); Cascading errors If inside the catch() you raise an error, you can append a second catch() to handle it, and so on. new Promise((resolve, reject) => { throw new Error('Error'); }) .catch((err) => { throw new Error('Error'); }) .catch((err) => { console.error(err); }); Orchestrating promises Promise.all() If you need to synchronize different promises, Promise.all() helps you define a list of promises, and execute something when they are all resolved. Example: const f1 = fetch('/something.json'); const f2 = fetch('/something2.json'); Promise.all([f1, f2]) .then((res) => { console.log('Array of results', res); }) .catch((err) => { console.error(err); }); The ES2015 destructuring assignment syntax allows you to also do Promise.all([f1, f2]).then(([res1, res2]) => { console.log('Results', res1, res2); }); You are not limited to using fetch of course, any promise can be used in this fashion. Promise.race() Promise.race() runs when the first of the promises you pass to it settles (resolves or rejects), and it runs the attached callback just once, with the result of the first promise settled. Example: const first = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'first'); }); const second = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'second'); }); Promise.race([first, second]).then((result) => { console.log(result); // second }); Promise.any() Promise.any() settles when any of the promises you pass to it fulfill or all of the promises get rejected. It returns a single promise that resolves with the value from the first promise that is fulfilled. If all promises are rejected, then the returned promise is rejected with an AggregateError. Example: const first = new Promise((resolve, reject) => { setTimeout(reject, 500, 'first'); }); const second = new Promise((resolve, reject) => { setTimeout(reject, 100, 'second'); }); Promise.any([first, second]).catch((error) => { console.log(error); // AggregateError }); Common errors Uncaught TypeError: undefined is not a promise If you get the Uncaught TypeError: undefined is not a promise error in the console, make sure you use new Promise() instead of just Promise() UnhandledPromiseRejectionWarning This means that a promise you called rejected, but there was no catch used to handle the error. Add a catch after the offending then to handle this properly.'Modern Asynchronous JavaScript with Async and Await' description: 'Discover the modern approach to asynchronous functions in JavaScript. JavaScript evolved in a very short time from callbacks to Promises, and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax' Introduction JavaScript evolved in a very short time from callbacks to promises (ES2015), and since ES2017 asynchronous JavaScript is even simpler with the async/await syntax. Async functions are a combination of promises and generators, and basically, they are a higher level abstraction over promises. Let me repeat: async/await is built on promises. Why were async/await introduced? They reduce the boilerplate around promises, and the "don't break the chain" limitation of chaining promises. When Promises were introduced in ES2015, they were meant to solve a problem with asynchronous code, and they did, but over the 2 years that separated ES2015 and ES2017, it was clear that promises could not be the ultimate solution. Promises were introduced to solve the famous callback hell problem, but they introduced complexity on their own, and syntax complexity. They were good primitives around which a better syntax could be exposed to the developers, so when the time was right we got async functions. They make the code look like it's synchronous, but it's asynchronous and non-blocking behind the scenes. How it works An async function returns a promise, like in this example: const doSomethingAsync = () => { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000); }); }; When you want to call this function you prepend await, and the calling code will stop until the promise is resolved or rejected. One caveat: the client function must be defined as async. Here's an example: const doSomething = async () => { console.log(await doSomethingAsync()); }; A quick example This is a simple example of async/await used to run a function asynchronously: title="Modern Asynchronous JavaScript with Async and Await" src=" https://stackblitz.com/edit/nodejs-dev-0007-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0007-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> Promise all the things Prepending the async keyword to any function means that the function will return a promise. Even if it's not doing so explicitly, it will internally make it return a promise. This is why this code is valid: const aFunction = async () => { return 'test'; }; aFunction().then(alert); // This will alert 'test' and it's the same as: const aFunction = () => { return Promise.resolve('test'); }; aFunction().then(alert); // This will alert 'test' The code is much simpler to read As you can see in the example above, our code looks very simple. Compare it to code using plain promises, with chaining and callback functions. And this is a very simple example, the major benefits will arise when the code is much more complex. For example here's how you would get a JSON resource, and parse it, using promises: const getFirstUserData = () => { return fetch('/users.json') // get users list .then((response) => response.json()) // parse JSON .then((users) => users[0]) // pick first user .then((user) => fetch(`/users/${user.name}`)) // get user data .then((userResponse) => userResponse.json()); // parse JSON }; getFirstUserData(); And here is the same functionality provided using await/async: const getFirstUserData = async () => { const response = await fetch('/users.json'); // get users list const users = await response.json(); // parse JSON const user = users[0]; // pick first user const userResponse = await fetch(`/users/${user.name}`); // get user data const userData = await userResponse.json(); // parse JSON return userData; }; getFirstUserData(); Multiple async functions in series Async functions can be chained very easily, and the syntax is much more readable than with plain promises: title="Multiple async functions in series" src=" https://stackblitz.com/edit/nodejs-dev-0008-01?index.js&zenmode=1&view=editor" alt="nodejs-dev-0008-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> Easier debugging Debugging promises is hard because the debugger will not step over asynchronous code. Async/await makes this very easy because to the compiler it's just like synchronous code. The Node.js Event emitter description: 'How to work with custom events in Node.js' If you worked with JavaScript in the browser, you know how much of the interaction of the user is handled through events: mouse clicks, keyboard button presses, reacting to mouse movements, and so on. On the backend side, Node.js offers us the option to build a similar system using the events module. This module, in particular, offers the EventEmitter class, which we'll use to handle our events. You initialize that using const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); This object exposes, among many others, the on and emit methods. emit is used to trigger an event on is used to add a callback function that's going to be executed when the event is triggered For example, let's create a start event, and as a matter of providing a sample, we react to that by just logging to the console: eventEmitter.on('start', () => { console.log('started'); }); When we run eventEmitter.emit('start'); the event handler function is triggered, and we get the console log. You can pass arguments to the event handler by passing them as additional arguments to emit(): eventEmitter.on('start', (number) => { console.log(`started ${number}`); }); eventEmitter.emit('start', 23); Multiple arguments: eventEmitter.on('start', (start, end) => { console.log(`started from ${start} to ${end}`); }); eventEmitter.emit('start', 1, 100); The EventEmitter object also exposes several other methods to interact with events, like once(): add a one-time listener removeListener() / off(): remove an event listener from an event removeAllListeners(): remove all listeners for an event You can read all their details on the events module page at https://nodejs.org/api/events.html'Build an HTTP Server' description: 'How to build an HTTP server with Node.js' Here is a sample Hello World HTTP web server: title="Build an HTTP Server" src=" https://stackblitz.com/edit/nodejs-dev-0009-01?index.js&zenmode=1" alt="nodejs-dev-0009-01 on StackBlitz" style="height: 400px; width: 100%; border: 0;"> Let's analyze it briefly. We include the http module. We use the module to create an HTTP server. The server is set to listen on the specified port, 3000. When the server is ready, the listen callback function is called. The callback function we pass is the one that's going to be executed upon every request that comes in. Whenever a new request is received, the request event is called, providing two objects: a request (an http.IncomingMessage object) and a response (an http.ServerResponse object). request provides the request details. Through it, we access the request headers and request data. response is used to populate the data we're going to return to the client. In this case with res.statusCode = 200; we set the statusCode property to 200, to indicate a successful response. We also set the Content-Type header: res.setHeader('Content-Type', 'text/html'); and we end close the response, adding the content as an argument to end(): res.end('<h1>Hello, World!</h1>'); 'Making HTTP requests with Node.js' description: 'How to perform HTTP requests with Node.js using GET, POST, PUT and DELETE' Perform a GET Request const https = require('https'); const options = { hostname: 'example.com', port: 443, path: '/todos', method: 'GET' }; const req = https.request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); res.on('data', (d) => { process.stdout.write(d); }); }); req.on('error', (error) => { console.error(error); }); req.end(); Perform a POST Request const https = require('https'); const data = new TextEncoder().encode( JSON.stringify({ todo: 'Buy the milk 🍼' }) ); const options = { hostname: 'whatever.com', port: 443, path: '/todos', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': data.length } }; const req = https.request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); res.on('data', (d) => { process.stdout.write(d); }); }); req.on('error', (error) => { console.error(error); }); req.write(data); req.end(); PUT and DELETE PUT and DELETE requests use the same POST request format - you just need to change the options.method value to the appropriate method. Make an HTTP POST request using Node.js description: 'Find out how to make an HTTP POST request using Node.js' There are many ways to perform an HTTP POST request in Node.js, depending on the abstraction level you want to use. The simplest way to perform an HTTP request using Node.js is to use the Axios library: const axios = require('axios'); axios .post('https://whatever.com/todos', { todo: 'Buy the milk' }) .then((res) => { console.log(`statusCode: ${res.status}`); console.log(res); }) .catch((error) => { console.error(error); }); Axios requires the use of a 3rd party library. A POST request is possible just using the Node.js standard modules, although it's more verbose than the two preceding options: const https = require('https'); const data = JSON.stringify({ todo: 'Buy the milk' }); const options = { hostname: 'whatever.com', port: 443, path: '/todos', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': data.length } }; const req = https.request(options, (res) => { console.log(`statusCode: ${res.statusCode}`); res.on('data', (d) => { process.stdout.write(d); }); }); req.on('error', (error) => { console.error(error); }); req.write(data); req.end(); Get HTTP request body data using Node.js description: 'Find out how to extract the data sent as JSON through an HTTP request body using Node.js' Here is how you can extract the data that was sent as JSON in the request body. If you are using Express, that's quite simple: use the body-parser Node.js module.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum A - C Ableton | Berlin, Germany | Take-home programming task (discussed via Skype), then pair programming and debugging session on-site Abstract | San Francisco, CA Accenture | San Francisco, CA / Los Angeles, CA / New York, NY | Technical phone discussion with architecture manager, followed by behavioral interview focusing on soft skills Accredible | Cambridge, UK / San Francisco, CA / Remote | Take home project, then a pair-programming and discussion onsite / Skype round. Acko | Mumbai, India | Phone interview, followed by a small take home problem. Finally a F2F or skype pair programming session Acumen | London, UK | Small take home test, and sit in on some sprint rituals on-site Addstones | Paris, FR / Singapore, SG / Bucharest, RO / London, UK | Multiple interviews, discussion of technical background and experiences. Sometimes we do a on-site unsupervised small exercise. Adnymics | Munich, DE | Take home project, then work with the team for a day Adthena | London, UK | Takehome project and discussion on-site AdWyze | Bangalore, India | Short takehome project + (for fulltime) onsite pairing AeroFS | San Francisco, CA | Short takehome project + phone interview Affinity | San Francisco, CA | Implementation of a children's game, then take-home project OR real-world design questions Ageno | Bielsko-Biala, Poland | Simple Magento Take-home project and discussion on the real world problems. AgileMD | San Francisco, CA | Takehome project Agoda | Bangkok, Thailand | Take-home project, then a discussion onsite round. Agrilyst | New York, NY / Remote | Short takehome project & remote pairing Airbrake | San Francisco, CA / Remote | Take-home project & pair on a problem similar to daily work Aiwip | London, UK | Skype/phone interview followed by takehome project or worksample (or whiteboard) Ajira | Chennai, India / Austin, TX | Take home project, then pair programming, technical discussions, cultural fit Algolia | Paris, France / San Francisco, CA | Takehome project & Onsite discussions and presentation all about apps GmbH | Vienna, Austria | 2-phase technical discussion & examination with department heads and management. Allegro | Warsaw, Poland; Poznan, Poland; Torun, Poland; Wroclaw, Poland; Krakow, Poland | Take home, simple project. Series of 2 technical interviews (how to build things, how to solve specific, real world problem) and meeting with a team leader. Alluvium | Brooklyn, NY | Take-home assignment, on-site review dovetailing into collaborative project planning for extension. AlphaSights | London, UK / New York, NY / Remote | Initial interview, pair programming then final round with general technical questions AMAGI | Makati, Philippines | 1) Review of your resume, portfolio, and/or GitHub profile; 2) 1 hour discussion (in-person or Skype) about your goals, experience, personal culture, and how to apply technical solutions to real problems; Analytical Flavor Systems | Manhattan, New York | Code sample or take-home project, both with discussion. Apollo Agriculture | Nairobi, Kenya/Remote | Takehome project or Worksample (or whiteboard) Applied | London, UK | Situational judgement tests focusing on real-world soft skills (online then in structured interview) Arachnys | London, UK | Take home test, real world pair programming Articulate | Remote | Take-home project & pair program on a problem similar to daily work Artsy | New York, NY / London, UK / Berlin, Germany / Los Angeles, CA / Hong Kong, Hong Kong / Remote | Our process: 1) Informal chat 2) Application 3) Phone screen 4) In-person interview with 1 lead, 2 individual contributors and 1 non-engineer (30-45 mins each), focusing on your work habits and expertise as demonstrated in your previous work 5) ~4 in-depth professional reference calls (30-45 mins each). ASI Data Science | London, UK | Project to work at home, general technical questions, pair programming with engineers ASOS | London, UK | Take home or in-person code refactoring exercise, in-person walk-though of solution including software crafstmanship principles and design decisions, in-person freestyle architecture walk-through Ataccama | Prague, Czech Republic | Face to face interview (skype or onsite), coding task for 30 min, meeting with team members aTech Media | London, UK | Face to face interview, review of existing open source contributions or, if none are available, asked to write a library for something that interests them Aura Frames | New York, NY / San Francisco, CA | Simplified real-world coding task on Coderpad.io, followed by a few hours onsite writing code in our actual codebase. Aurora Solar | San Francisco, CA | Our process: 1) Initial phone call 2) 1 hour take home project in CoderPad along with a few essay questions relating to JavaScript, testing, etc. 3) Remote pairing session solving a problem similar to day to day work. 4) In-person interview with additional pairing exercise done on a laptop as well as culture interviews. Auth0 | Bellevue, WA / Buenos Aires, Argentina / Remote | Series of interviews, go over technical background and past experiences, take-home project Auto1 | Berlin, DE | Series of Skype interviews which covers general technical questions, followed by a take-home assignment Automattic | Remote | short take-home real-world task, then a few weeks-long real-world, part-time, and paid project on production code AutoScout24 | Munich, Germany | Skype interview followed by home assignment from our day-to-day business and then on-site interview including lunch with a team Avant | Chicago, IL | Pair programming interviews. Avarteq GmbH | Berlin, Germany / Saarbrücken, Germany | Technical interview with our developers on-site or remote followed by a work sample in a pair programming session or a previous take-home project with a follow-up discussion and detailed feedback. Avocarrot | Athens, Greece | on-site real world problem discussion and pair programming Axelerant | Remote | Take-home project, interviews with hr and engineering team. Axiacore | Bogota, Colombia | We talk about on how is your process when solving problems. Axios | Arlington, VA / New York, NY / San Francisco, CA / Remote | Take-home project, with discussion. B12 | New York, NY | Take-home exercises and pair-programming with the team. B2W Digital | Rio de Janeiro, Brazil; São Paulo, Brazil | Time-boxed coding exercise at home, on-site pair programming with engineers and live software architecture challenges based on real situations. Babylon Health iOS Team | London, UK | Take-home project, on-site presentation and discussion, design and product interview. Backbase | Amsterdam, Netherlands; Cardiff, Wales; London, UK; Atlanta, GA | Takehome project, interviews Badi | Barcelona, Spain | Phone Screen, Take-home project, then a discussion onsite round. Badoo | London, UK | Take-home project, then a discussion onsite round. BAE Systems Applied Intelligence | London, UK | Initial interview with experience based technical questions, second interview pair programming on problem similar to daily work Bakken & Bæck | Oslo, Norway; Amsterdam, Netherlands; Bonn, Germany | Skype interview followed by take-home assignment and a visit to one of our offices Balabit | Budapest, Hungary | Take-home project (medium size, with restrictions, e.g. only stdlib may be used), then discussion on-site Barracuda View Team | Chelmsford, MA / Remote | Phone screen, remote pair programming session, technical discussion interview, culture fit interview Basecamp | Chicago, IL / Remote Beam Dental | Columbus, OH | Phone Screen, Take Home Project, In-Person Pairing and Cross-Functional Interview Belka | Trento, Italy; Munich, Germany | We give you a small task that you can do alone and then we evaluate your work with you Bemind Interactive | Biella, Italy / Latina, Italy / Remote | Series of interviews, discussion about technical background and past experiences, take-home project & pair programming Bendyworks | Madison, WI | Interviews and pair programming on personal projects Betterment | New York, NY | Phone interview followed by on-site pair programming to simulate a Betterment feature build. BetterPT | New York, NY | Initial phone interview, project using our tech stack, on-site code review/pair programming and "meet the team". Big Nerd Ranch | Atlanta, GA & Remote | Interviews and pair programming on an internal project or problem. BioConnect | Toronto, Canada | Take-home assignment & discussion bitExpert AG | Mannheim, Germany | Interview with experience based technical questions Bits of Love | Bruges, Belgium | In-person interview to evaluate experience and motivation, potentially followed by take-home project. Blackdot Solutions | Cambridge, UK | Take-home project followed by on-site face-to-face walkthru of your code focusing on decisions/reasoning/technology used. Bleacher Report | San Francisco, CA, USA | Take-home project; on-site discussion about the project and meeting with different teams Blendle | Utrecht, The Netherlands | Take-home project & pair program on a problem similar to daily work blogfoster | Berlin, Germany | Take-home project, discussion on-site Blue Bottle Coffee | Oakland, CA | Technical Phone Screen, Take Home Challenge, Technical in-persons. Bluesoft | São Paulo, Brazil | Takehome project and an interview to evaluate the candidate's previous experience. Bocoup | Boston, MA / Remote | Pair programming with personal laptop on typical problem seen at work Bolste | Phoenix, AZ | Conversational in-person interviews with team members and pair programming through real world problems BookingSync | Remote | Small takehome project, interviews over skype with team members. BoomTown | Charleston, SC / Atlanta, GA / Remote | Conversational in-person interviews with potential team members and managers that revolve around past experience and how that could be applied to future work Bouvet | Bergen, Norway | Pair programming with senior engineers brainn.co | São Paulo, BR | Zoom/On-site interview, take-home project and interview with a team leader. BrainStation-23 | Dhaka, BD | A practical project followed by series of in-person interview sessions Breather | Montreal, Canada | Series of interviews including a conversation about the candidate's experience and a technical discussion involving real world problems BrightBytes | San Francisco, CA | Time-boxed coding exercise at home and on-site pair programming with engineers BrightHR | Manchester, UK | Telephone conversation, coding exercise at home, on-site pairing with a cultural interview, meet the team. brightwheel | San Francisco, CA | Take home exercise, and systems design. Broad Institute's Data Sciences Platform | Cambridge, MA | Phone screen, small take home project, both a technical and non-technical discussion panel, and a panel following up on the take home project walking through the solution and making a modification to the original code Bubblin Superbooks | Remote | View code, projects, libraries or any other open source story that you have been a part of, a small take-home project with real code occasionally. Buffer | Remote | Interviews over video call, code walkthrough of real code focussing on decisions and reasoning, then a 45 day full time, fully paid contract project working on production code. Bugcrowd | San Francisco, CA / Sydney, NSW | Take home exercise, half-day onsite walking through code, and pair programming. Buhler Group | Prague, CZ | Interview with a couple of technical questions. No task needed. Depending on the team there is another round with the guys in the HQ via skype. Bulb | London, UK | Phone screening, followed by a 2-4 hours take home task. If successful, on-site interview to discuss and extend with the reviewer and one other engineer, followed by 2x informal "Meet the team" interviews. Busbud | Montreal, Canada | Phone screening, followed by a 2-4 hours take home assignment. If the challenge is a success, on-site or remote interview with team members, including someone who reviewed it, to talk about it and potential next steps if the challenge was a real life task. Bustle | New York City, Ny / Remote | Half day pair programming on a task for production or one of our Open Source projects. We'll also buy you lunch with the team. busuu | London, UK | Video call to show real code as first stage. In office pair programming, white board real world problem that we've encountered before, and history/experience discussion. ButterCMS | Chicago, IL; Remote | Take home exercise and half-day of pair programming ByBox | Remote | Phone interview followed by interview with devs (ideally in person but sometimes Skype) covering technical experience and coding exercise with real code. CACI Rome | Rome, NY; Remote | Phone interview followed by in-person or Skype screen sharing interview with a coding exercise in either Java, web (Node.js + frontend), or both. Interview format is exclusive to the Rome, NY office and may not be shared by other regional CACI offices. Cake Solutions | Manchester, UK; London, UK; New York, NY | Skype / Hangouts / phone call to explain the technical background, current position and set expectations about the salary, relocation, etc; if all good, what to expect next. Then take-home exercise for roughly 4 hours to demonstrate good thinking and ability to pick up new things, explain & document the solution, finishing with pair programming with senior developers (remote or in person); use the code as a talking point around the more difficult things after getting through the simple starter tasks. Capgemini UK Java Team | London, UK; Woking, UK; Bristol, UK; Cardiff, Wales; Birmingham, UK; Manchester, UK; Leeds, UK; Rotherham, UK; Liverpool, UK; Newcastle, UK; Edinburgh, Scotland; Glasgow, Scotland | Technical telephone interview (30 minutes), take-home non-CompSci coding exercise (3-4 hours), face-to-face role-played consulting scenario involving a solution architecture and a delivery plan (two hours) Caravelo | Barcelona, Spain | Take home project, then technical discussion about the code in-person or Skype and hang out with the team. Cartegraph | Dubuque, IA / Remote | Phone screen, hiring manager interview, small take-home coding project, and team code review/interview CARTO | Madrid, Spain | Phone screen, take-home project, team code review/interview, hiring manager interview Casetext | San Francisco, CA | Submit code sample for review/discussion, contract for one full day (paid) CASHLINK | Frankfurt, Germany | Skype/phone interview, take-home project Causeway | United Kingdom, India | Skype or Telephonic discussion on approaches and experience in regards to solve projects related work, then face to face round to write small solutions to common problems in related field. Centroida | Sofia, Bulgaria | Series of interviews, pair programming and take-home projects Chain.Reaction | Budapest, Hungary | Partnership-fit discussion, code-review and trial days. Chargify | San Antonio, TX / Remote | Take-home project & pair on a problem similar to daily work Checkout 51 | Toronto, Canada | Phone conversation (15-20 minutes) followed by on-site pair programming and discussion focused on understanding decisions made during on-site work Chesapeake Technology | Denver, CO / Santa Barbara, CA / Camarillo, CA / Dulles, VA / California, MD / Remote | Phone screen (30 minutes), take home at leisure question based on real development followed by in person review of solution and general technical questions with actual team and opportunity for you to ask questions and provide feedback ( 2-3 hours) CircleCI | San Francisco, CA / Remote | Take-home project and discussion, followed by on-site interview that includes pair programming on actual CircleCI bugs/feature requests. City of Boston's Analytics Team | Boston, MA | Take-home project and in-person or phone/Skype interviews City of Philadelphia's Office of Open Data & Digital Transformation | Philadelphia, PA | Take-home project Civis Analytics | Chicago, IL | Take-home project and discussion via Skype, followed by pair programming exercise CJ Affiliate | Los Angeles, CA & Westlake Village, CA | Phone coding design exercise (no algorithms), followed by an on-site final interview that includes pair programming on a realistic object-oriented design problem Clara Lending | San Francisco, CA | Phone conversation around technical background and experience, followed by take-home project, pair programming and discussion Clerkie | San Francisco, CA | Phone conversation followed by take-home project ClickMagick | Austin, TX / Remote | Phone conversations and examples of Free Software/Open Source work Clippings | Sofia, Bulgaria | Video screening first, then send us code they've recently wrote, then technical interview. We could ask questions about the code they wrote at home. Clockwork Consulting | Copenhagen, Denmark | Interviews, discussion of technical background and experiences. Cloudistics | Reston, VA | Multiple interviews, discussion of technical background and experiences. Clubhouse | New York, NY & Remote | Phone interview, followed by onsite discussions and pair programming Cogent Labs | Tokyo, Japan | On-site or video call conversation around technical background and experience, followed by take-home project that resembles a problem Cogent Labs solves for. This project will serve as the base of discussion with the developers for the second interview. Cognitect, Inc. | Remote | Phone interview followed by pair programming. Cognitran | Essex, UK / Szczecin, Poland / Detroit, MI | Skype/phone interview followed by pair programming. Collabora | Cambridge, UK / Montreal, Canada / Remote | On-site or video interview, discussion of technical experience and sometimes approach for tackling a hypothetical problem. COMPEON | Duesseldorf, Germany | Phone interview, followed by onsite discussions and pair programming with our developers Concordia Publishing House | St Louis, MO | Take-home project followed by discussion of it on-site with future teammates. Contactlab | Milan, Italy | Recruiter interview, tech interview (technical background and experiences), both on-site. Contentful | Berlin, Germany & SF, USA | Multiple interviews, discussion of technical background & live coding challenge (you can use the internet). ContentSquare | Paris, France | Real-world challenges with open discussions. Cookpad | Tokyo, Japan; Bristol, UK | Interviews, discussion of technical background and experiences, remotely pair with devs. Coorp Academy | Paris, France | Technical interview as an open discussion CoverHound, Inc. | San Francisco, CA | Open technical discussion, short on-site coding challenge. Credit Kudos | London, UK | Take-home project and pair programming via Skype or on-site. CrossBrowserTesting | Memphis, TN | Take home project that resembles a problem support engineers deal with on a daily basis. On-Site interviews in a comfortable environement with a focus on hiring talented people vs exact skill-sets. Crowdstrike | Remote | Multiple interviews onsite or remote as appropriate followed by small take-home project. Crownstone | Rotterdam, Netherlands | Technical interaction using previously created Github projects, followed by in-person interview with a focus on someone's professional ambition in the short and long term. cube19 | London, UK | Take-home project, then an on-site discussion about the code and previous experience. Cultivate | Edinburgh, UK | 30 minute pair-programming screening interview on a simple exercise (remote or in-person). Half day pair programming, with 3 or 4 different team members plus informal chat, typically on-site. Culture Foundry | Austin, TX | Paid take-home project CurrencyTransfer | London, UK & Remote | Take-home project D - F Dark Sky | Cambridge, MA | Phone interviews and a very short, real paid project Data Theorem | Palo Alto, CA; Paris, Fr; Bangladesh, India | Phone interview, then a take home project and finally in-person interview. Datalogue | Montreal, Canada | We Ask candidates to contribute meaningfully to an Open source project that reflects the stack they will be working with and send us a link to the PR. DataMade | Chicago, IL | After submitting an application, selected applicants are moved on to a round of interviews and will be asked to submit a piece of code for review. If you don't have any code you can share, DataMade will provide a short exercise for you to complete. An in-person (or remote) interview will be scheduled to go over your background, what draws you to DataMade, and your code sample. Datascope | Chicago, IL | Take home exploratory data project with public data, discussion about the project via video chat, and in-person office visit. Datlinq | Rotterdam, Netherlands | Take-home project based on actual work on data done by the team and in-person or Skype interviews DealTap | Toronto, Canada | Technical Interview, Solution Design, Take Home Assignment, then Culture fit interview with the team, and optional pair programming. Def Method | NYC, NY | Take home test, pair programming with dev on test and client work, receive offer same day as pairing interview Deliveroo | London, UK & Remote | Short take-home project and pair programming Dentolo | Berlin, Germany | Phone interview with the HR department, take-home project and technical interview to discuss your skill set + general questions Deskbookers | Amsterdam, Netherlands | Phone screen, take-home project, on-site interview DeSmart | Gdynia, Poland | Technical interview, take-home project and talk about your experience Despark | Sofia, Bulgaria & Remote | Culture add interview, sample code review and paid pair programming with team member or take-home project. Detroit Labs | Detroit, MI | Our technical interview starts with a take-home assignment that we will look at during the interview. You'll walk us though your thought process, add functionality if applicable to the interview, and talk about your experience. We believe that showing us your work in a practical setting is more telling of your abilities and what you will bring to the table, than writing code on a whiteboard. DevMynd | Chicago, IL; San Francisco, CA | Take-home project, take-home project phone review, a few hour-long pairing sessions on real projects. DG-i | Cologne, Germany | Take-home project and/or discussion on-site about past experiences DICE | Stockholm, Sweden | Take-home project and code review at the on-site Digitally Imported | Denver, Colorado & Remote | Video meetings on past experience and high level tech questions, take-home project Dollar Shave Club | Venice, California | Phone interview, take-home projects, on-site interview door2door | Berlin, Germany | Take home challenge + on-site interview + trial day DoorDash 🏃💨 | San Francisco, CA | Take home project + an on-site interview building off the project! Draft Fantasy | Tel Aviv, Israel | Talk about past experience and what the developer has actually built as well as pair programming or a programming exercise. Drawbotics | Brussels, Belgium | Take-home project, bootcamp on-site drchrono | Mountain View, CA | Hackerrank test (but not CS trivia, it's real product problems) & on-site/take-home project w/ presentation Drivy | Paris, France | Phone screening followed by a take-home assignment, "Resume" interview, technical interview, product interview, interview with another team, finalizing the hire DroneDeploy | San Francisco, CA | Pair program on a problem similar to daily work DroneSeed | Seattle, WA | Take home assignment of a real problem we've worked on, group code review in subsequent interview. dubizzle | Dubai, UAE | Take home assignment, general technical questions, pair programming with engineers or tech leads E-accent | Hilversum, Netherlands; Remote | Skype conversation, take-home assignment Easy Taxi | São Paulo, Brazil | Take-home project, interview to evaluate the candidate's previous experience. Eaze | San Francisco, CA | Take home project, on-site interview building off of the project eBay Kleinanzeigen | Berlin, Germany | 45 mins technical phone interview, take-home project/review, on-site interview including pair programming with team lead and agile interview with product manager. Echobind | Boston, MA; Remote | Meet the entire team, share examples of previous work and pair with one team member Edenspiekermann | Amsterdam, Netherlands / Berlin, Germany / Los Angeles, CA / San Francisco, CA / Singapore, Singapore | On-site chat about skills and past experiences, review some code samples or a take-home assignment EF Education First | London, UK; Boston, MA | Short phone interview, take-home project, discussion of project and real world engineering problems, meet the team. Eidu | Berlin, Germany | Take-home project, discussion of results with team, and test days with pair programming El Passion | Warsaw, Poland | Take-home project, interview to 1) discuss delivered solution and 2) previous projects Electric Pulp | Sioux Falls, SD, USA | Phone interviews with leadership team and technical team leads. We are a tight knit team, so emphasis on a great personal fit is as important as technical prowess. Elements Interactive | Almere, The Netherlands & Barcelona, Spain | Take-home project & discussion via Skype or on-site Ellucian | Reston, VA, USA | Discussion of real world problems (from resume, if possible) elmah.io | Aarhus, Denmark / Remote | Discussion about code and looking at hobby projects (if any) Elvie | London, England | Discussing real code, pairing and a paid day to see how you work with the team. No coding for free or time-restricted take-home projects, code challenges or abstract algorithm tests eMarketer | New York, NY | Short phone interview, then come in and meet the team, check out our space, and have a discussion with team members about real-world problems Emarsys | Budapest, Hungary | Take-home project (small, 1-2 days to solve), then discussion on-site Endava | Belgrade, Serbia; Bucharest, Romania; Chisinau, Moldova; Cluj-Napoca, Romania; Iasi, Romania; Pitesti, Romania; Skopje, Macedonia; Sofia, Bulgaria; Frankfurt, Germany; Glasgow, Scotland; Hilversum, Netherlands; London, UK; Oxford, UK; Bogota, Colombia; Atlanta, GA; New Jersey, NJ; New York, NY | On-site discussion about previous experience and technical questions about the target technologies. Engel & Völkers Technology | Hamburg, Germany | Remote technical interview with an Engineering Manager, followed by a practical coding challenge implemented in 5 hours, ending with a technical discussion with the team on the produced code either remotely or on-site based on geographical practicality. Enhancv | Sofia, Bulgaria | Talk is cheap, show us your code: github profile or other project examples. Explain them in person / remotely. Discuss habits and interests to see if we have a culture fit. Enigma | New York, NY | 2-part takehome project, followed by a pair programming exercise Enki | London, UK | Skype/phone interview followed by takehome project Ento.com | Melbourne, Australia | On-site interview to talk about your experiences and what you're looking for in your next role, followed by a take-home practical test relevant to the work you'll be undertaking at Ento. Equal Experts | London, UK; Manchester, UK; New York, NY; Pune, India; Lisbon, Portugal; Calgary, Canada | Fizzbuzz test done at home followed by Pair Programming session at office and finally face to face technical and attitude interview. Ericsson | Dublin, Ireland | Skype/phone interview followed by Face 2 Face interview, discussions and architecture questions followed by final small project on a problem similar to daily work. eShares, Inc | San Francisco, CA; Palo Alto, CA; Seattle, WA; Rio de Janeiro, Brazil; London, UK; New York, NY | Phone call, practical technical screen, on site to meet the team & explore the company Etix Everywhere | Luxembourg City, Luxembourg EURA NOVA | Mont-Saint-Guibert, Belgium; Marseille, France; Tunis, Tunisia | attitude interview, unpaid take-home project, technical discussion with 1 or 2 technical employees (remote or face 2 face), face 2 face discussion with HR, partner, and technical staff to have a foretaste of the collaboration Euro Payment Group | Frankfurt, Germany | Take-home project followed by face to face interview Exoscale | Bern, Switzerland | Take-home project. Discussion and presentation. Then entire team meet. F(x) | São Paulo, Brazil | Skype interview, Take-home project and onsite interview to evaluate the candidate Falcon.io | Copenhagen, Denmark | Initial call/Skype culture interview. Take-home tech assignment (game) and code review. On-site Interview about your experience and meeting the team. FATMAP | London, UK; Berlin, Germany; Vilnius, Lithuania | Skype discussion, Take-home project, Face to face Fauna | San Francisco, CA / Remote | Take home project, then follow up with interviews on-site or remote. Interviews are both technical and non-technical. Technical interviews comprehend the scope of the home project. Feather | Remote | Take-home challenge, portfolio discussion & team meeting Findy | Tokyo, Japan | Tech interview + On-site discussion FINE | Portland, OR | Small take-home challenge + follow-up discussion Firemind | Maidstone, UK; London, UK; Remote | Small pre-interview challenge on github + discussion face to face in person or via video Fitbot | Boulder, CO | Pairing & writing code with the founders for a few hours Flatfox | Zurich, Switzerland | Informal conversation to check mutual fit, small (4h) take-home assignment, discussion in team Fluidly | London, UK | Casual 30min phone call. ~1hr take home tech exercise (not pass or fail). 1 stage onsite interview - discussion about experience, 1 hour pair programming on the real code base, then your turn to interview us! Food52 | New York, NY; Remote | Take-home project, discussion on-site or remote, interviews with both technical and non-technical staff Fooji | Lexington, KY; Remote | Take-home project Formidable Labs | Seattle, WA; London, UK; Remote | Take-home project, remote pair programming, discussion on-site or remote Fortumo | Tallinn, Estonia; Tartu, Estonia | After a 30-min call you get a simplified version of a task that has recently been a challenge for the engineering team Founders | Copenhagen, Denmark | Take Home project + Interviews Foundry Interactive | Seattle, WA | On-site or remote discussion, paid trial project with pairing and code reviews fournova | Remote | Take-home project, discussion via video call FreeAgent | Edinburgh, UK | Take-home project, pair programming, discussion and interviews Freeletics | Munich, Germany | Small real-world challenge, multiple interviews on-site/remote and social gathering with team. Freetrade | London, England | Initial hangout with fizz buzz style question followed by an on-site real world coding question and systems design conversation. FRIDAY | Berlin, Germany | Take-home real-world challenge, interview on-site or remote Frontside | Austin, Texas | Phone interview with remote pairing session. Followed by in person pairing (paid for the day) and lunch with the team. Funda | Amsterdam, The Netherlands | Take Home test + Discussion On-Site/Remote FundApps | London, UK | Coffee with an Engineer; take-home kata; code review + on-site pair programming exercise. G - I Gamevy | London, UK; Bilbao, ES; Remote | Informal culture discussions, pair programming with our engineers Garner | Toronto, Canada | step 1: online chat with hiring manager, step 2: at home assignment solving real-life problem, step 3: on-site pair programming with engineers, step 4: offer GatherContent | Remote | Culture-first interviews, pair programming and remote, informal technical discussions GeneralUI | Seattle, WA | A short phone screen with questions regarding general knowledge related to the open position, then a half day pair programming interview. Ginetta | Zurich, Switzerland; Braga, Portugal | Culture-first interviews, take home assignment that resembles a real-world problem we often solve, then discussion about the assignment in-person with pair-programming improvement sessions with our developers. GitHub | Remote; San Francisco, CA; Boulder, CO| Take-home exercise, code review and technical discussions. GitPrime | Denver, CO; Remote | small short term real-world project, paid project on production code Glints | Singapore, Singapore; Jakarta, Indonesia | Culture fit interview, take home assignment that resembles a real-world problem, walkthrough about the assignment GoCardless | London, UK | Project to work at home, general technical questions, pair programming with engineers GoDaddy | Sunnyvale, CA | Pair programming with senior engineers GoJek | Bangalore, India; Jakarta, Indonesia; Singapore, SG; Bangkok, Thailand | Take-home exercise, Pair programming with senior engineer, Techinal problem solving and discussion, Cultural Fit Gower Street Analytics | Remote; London, UK | Initial telephone chat, then either a) work with us, fully paid, for a day on real code with the team; or b) pair-programming on a code kata with the team members for four pomodoros. Your choice. Graffino | Sibiu, Romania | Take-home project, discussion on-site Grafton Studio | Boston, MA | Take-home project, discussion on-site Gramercy Tech | New York, NY | Pair programming & discussion on-site grandcentrix | Cologne, Germany | Take-home project, discussion on-site Grape | Vienna, Austria / Remote | Github or code samples -> Pair programming -> Skype/phone interview Graphcool | Berlin, Germany | On-site pair programming of a small, isolated real world task Graphicacy | Washington, DC | Phone interview; in-person or virtual interview depending on location and availability; two brief technical assignments focused on flexibility, creativity, and general competency Graphistry | Oakland, CA; San Francisco, CA; Remote | Engineering, culture, and product discussions, and for junior developers, choice of take home or code review. Grok Interactive | San Antonio, TX | Take-home project with code review and a follow-up in-person interview. Gruntwork | Remote | Paid, take-home project with pair coding GTM Sportswear | Manhattan, KS / Remote | Remote pairing session, then a take-home test. Happy Team | Warsaw, Poland; Remote | General technical questions, takehome paid exercise with feedback/discussion during implementation Happypie | Uppsala, Sweden | Takehome excercise with code review after, in-person interview Hash | Sao Paulo, Brazil | Take-home project and/or discussion (on-site or remote) Hashrocket | Chicago, IL/Jacksonville Beach, FL | Remote pairing session, paid week pair programming with everyone on the team Headspring | Austin, TX; Houston, TX; Monterrey, Mexico | Take-home situational questionnaire and code exercise, with in-person follow up to discuss and pair for changes Healthify | Remote & New York City, NY | Take-home project, discussion via Zoom, pair programming with us on our app for a day. Heetch | Paris, France | Values-fit interview (via zoom.us), Take-home project with review, Team Discussions (via zoom.us), on-site day HE:labs | Rio de Janeiro, Brazil & Remote | Take-home project and discussion via Skype. HelloFresh | Berlin, Germany | Take-home project, discussion via Skype or on-site Heptio | Seattle, WA; Remote | Take-home project, discussion on-site Hill Holliday | Boston, MA | Take-home project on GitHub, in-person interview / culture fit interview Hireology | Chicago, IL; Remote | Walk through personal/work projects and discuss experience Hiventive | Pessac, France | Phone interview, home coding challenge, on-site interview with general programming questions, discussion of proposed solutions and personal experience. HolidayPirates | Berlin, Germany | Take-home project, discussion via Skype or on-site HoloBuilder | Aachen, Germany | Take-home project, discussion via Skype or on-site Home Chef | Chicago, IL; Remote | Get-to-know-you meeting with the team, followed by a half-day collaborative coding session HomeLight | San Francisco, CA; Scottsdale, AZ; Seattle, WA | Phone screen, take home that is close to production code, onsite with pair programming HoxHunt | Helsinki, Finland | Take-home project, pair programming on-site Human API | Redwood City, CA | Technical phone interview, then on-site pair programming and design discussion I|O | Cape Town, South Africa Icalia Labs | Monterrey, Mexico | Pair programming, cultural fit session iConstituent | Washington, DC | Take-home project and code review in-person Ideamotive | Warsaw, Poland & Remote | Take-home project, technical interview with developer IDEO | San Francisco, CA; New York, NY; Chicago, IL; Cambridge, MA | Take home project that resembles a problem IDEO solves for, then pairing session in person or over video chat. ImmobilienScout24 | Berlin, Germany | Take-home project, discussion on-site Impraise | Amsterdam, The Netherlands | Take home test, real world pair programming Incloud | Darmstadt, Germany | Technical interview with developers, followed by a full day on site with a practical project Indellient | Oakville, Canada | Series of interviews both technical and non-technical InfluxData | San Francisco, CA & Remote | Technical and non-technical interviews, pair programming, with prospective manager and multiple prospective teammates InfoSum | Basingstoke, UK | On-site unsupervised exercise & discussion. inKind Capital | Boulder, CO | Discussing real-world problems, pair programming, dinner & drinks with the team Inmar | Winston-Salem, NC; Austin, TX & Remote | Take-home project and conversation-style interviews Innoplexus | Pune, India; Frankfurt, Germany | Take-home projects and On-site pair programming assignment. Instacart | San Francisco, CA | Take-home real world project, pair programming on-site InstantPost | Bangaluru, India | Remote assignment followed by Technical and Team round interview Integral. | Detroit, MI | Initial remote technical screen featuring test-driven development & pair programming, then on-site full day interview that involves pair programming on production code using test-driven development. Intelipost | São Paulo, BR | Take-home project, on-site code review and presentation (skype available if needed), discussion involving real world problems and interviews with different teams Intercom | San Francisco, CA; Chicago, IL; Dublin, Ireland | Real-world technical design and problem discussion, pair programming on-site Interset | Ottawa, Canada | Discussion of technical background and past experience. Relevant take-home project for junior developers Ithaka | Mumbai, India | Phone interview followed by a small development task. Finally a phone interview with CEO. iTrellis | Seattle, WA | Phone screen, then a take-home project, then pairing (remote or on-site) with 3 developers on the take-home project. iZettle | Stockholm, Sweden | Remote pair programming exercise, propose an architecture for an application and discuss about it in an informal format. J - L Jamasoftware | Portland, OR | Initial phone screen with hiring manager. In person pairing on project similar to day-to-day work with a separate cultural interview Jamit Labs | Karlsruhe, Germany | Phone interview or on-site interview & take-home code challenge or on-site programming session Jiminny | Sofia, Bulgaria | Phone screen. Take-home exercise. Follow-up discussion. Jitbit | Remote; London, UK; Tel-Aviv, Israel | Take-home real-world task Jobtome | Stabio, Switzerland | Phone screen introduction with hiring manager. In site (or screen call) with Engineer Manager for a talk on skills and cultural fit. Journal Tech | Los Angeles, CA | Mini take-home project, phone interview, discussion on-site Journalism++ | Berlin, Germany | Apply through a relevant online challenge to show your technical skills and your capacity to investigate JustWatch | Berlin, Germany | Take-Home project, discussion on-site K Health | Tel Aviv, Israel | Phone screening to discuss technical background and past experience. Take-home assignment followed by on-site code review and interview. Cultural fit assessment Kahoot! | London, UK / Oslo, Norway | Phone screening to discuss technical background and past experience. Take-home assignment followed by on-site code review and interview. Cultural fit assessment Kata.ai | Malang, Indonesia / Jakarta, Indonesia | Take-home assignment, then invited to discuss the assignment and interview. Kayako | London, UK / Gurgaon, India | Take-home assignment, series of experience based interviews, cultural fit assessment Kentik | San Francisco, CA | Phone screening to discuss technical background and past experience. Take-home assignment followed by on-site code review and interview. Cultural fit assessment Keymetrics | Paris, France | Phone Interview, Take-home project based on our API, IRL meeting with the whole team Kindred Group, Native Apps Team | Stockholm SE, London UK | On-site/Skype programming task, Interview Kinnek | New York, NY | Phone screen, on-site pairing session, take-home project Kiwi.com | Brno, Czech Republic | Phone Interview, Take-home projects, On-site code review & interview KNPLabs | Nantes, France | First step: screening call directly with the CEO, to discuss company vision, assess cultural fit and experience. Second step: call or IRL interview with a developer and a project facilitator , technical discussions with focus on soft skills. The goal of the interview is for the 2 KNPeers to be able to answer: “Do I want to work with this person ?” If both say yes, the person is hired. If even at least one says no, the person is not hired. Koddi Inc. | Fort Worth, TX | Phone Interview(s), take-home project, on-site interview Kong | San Francisco, CA | Phone interview. Pairing and technical interviews. Take home assigment. Kongregate | Portland, OR | Phone screening. Take home project. On-site pairing and conversational technical interviews. Korbit | Seoul, South Korea | Take home assignment followed by on-site code review and interview Lab.Coop | Budapest, Hungary | Partnership-fit discussion, code-review and trial days. Landing.jobs | Lisbon, Portugal | Interviews (in-person or remote), Take home coding project Lanetix | San Francisco, CA | Our Hiring Process LateRooms | Manchester, UK | Telephone interview followed by coding problem at home. Suitable submissions proceed to an onsite interview. Launch Academy | Boston, Philadelphia | Nontechnical phone screen, pair programming with team member, and potentially a "guest lecture" for our students LaunchDarkly | Oakland, CA | Informational phone screen with Eng leadership, take home project, onsite interviews Learningbank | Copenhagen, DK | Take home assignment, followed by on-site code review. Legalstart.fr | Paris, France | Telephone interview followed by take-home challenges. Suitable applicants are asked to do further on-pair interviews on site. Leverton | Berlin, Germany | Initial chat with the HR continued with 1-2 rounds chat with the team; followed by a technical test and finally a chat with the CTO/MD. Jobs page Liberty Mutual | Seattle, WA; Boston, MA; Indianapolis, IN | Initial interview, discussion on-site, interview with peers Librato | San Francisco, CA; Boston, MA; Austin, TX; Vancouver, Canada; Krakow, Poland | Take home coding project, conversational technical interviews on-site Lightning Jar | San Antonio, Tx | Remote pairing session, Initial interview,discussion on-site Lightricks | Jerusalem, Israel | Initial interview, Take home project, discussion on-site LinkResearchTools | Vienna, Austria | Skype interview, mini take-home exercise, discussion on-site / personal interview Listium | Melbourne, Australia | Design and code proof of concept features with the team Litmus | Remote | General technical questions, take-home code challenge, discussion, on-site programming session, meet & greet with the team LittleThings | New York, NY | Take home code challenge, Discussion LoanZen | Bengaluru, India | Initial phone interview about experience, a solve-at-home project based on the kind of work we do at our company, on-site interview discussing the submitted solution and a general discussion with the whole team Lob | San Francisco, CA | Initial phone screen followed by an on-site interview. Technical problems discussed during the interview are all simplified versions of problems we've had to solve in production. Our entire interview process and what we're looking for is described in our blog post How We Interview Engineers. Locastic | Split, Croatia | Take-home code challenge, tehnical discussion & on-site programming session, meet & greet with the team Locaweb | São Paulo, Brazil | Skype interview, take-home project and discussion on-site LOGIBALL GmbH | Berlin, Hannover and Herne in Germany | Interviews and discussion Logic Soft | Chennai, India | Phone discussion, F2F pair programming exercise + discussion LonRes | London, United Kingdom | Quick introduction call with tech (Skype), coding task for ≈1 hour, face-to-face interview (or via Skype) and meeting with team members. LookBookHQ | Toronto, Canada | On-site discussion, pair programming exercise Loom | San Francisco, CA | Google Hangouts resume dive on past experience, take-home project OR architectural phone screen, on-site interviews (2 technical architecture related to work, 1 or 2 non-technical) Lydia | Paris, FR | Mini take-home project, phone interview, discussion on-site Lyft | San Francisco, CA | Pair programming on-site with your own personal laptop Lyoness Austria GmbH | Graz, Austria | Take-Home project, discussion on-site M - O Made Tech | London, UK | Our hiring process Magnetis | São Paulo, Brazil & Remote | Phone interview + take home assignment, followed by pair programming and informal meeting with the team. Major League Soccer | New York, NY | Phone interview + short take home project, which is daily work focused. In person interview could involve discussing past projects or pair programming. MakeMusic | Boulder, CO; Denver, CO | Phone screen, take home project, remote and on-site interviews for technical and cultural fit MakeTime | Lexington, KY | Practical exercise and/or a pairing session on site Mango Solutions | London (UK), Chippenham (UK) | Initial phone interview, followed by on-site interview with take-home assignment Mapbox | San Francisco, CA; Washington, DC; Ayacucho, Peru; Bangalore, India; Berlin, Germany; Remote | Conversational interviews, paid onsite project with team. Mavenlink | San Francisco, CA; Irvine, CA; Salt Lake City, UT | On-site pairing with multiple engineers. Pairing exercises and pairing on company code. Maxwell Health | Boston, MA | Take-home exercise or pairing session with team. Then conversational meetings with members of the team. Me & Company | Düsseldorf, Germany | You join us for one or two paid trial days to work on an assignment and to meet the team. Media Pop | Singapore, Singapore | Take-home or unsupervised (onsite) real-world assignment Meetrics | Berlin, Germany | Initial interview, take-home code challenge and review Meltwater | Manchester, NH | Small take home exercise that will be presented to the team during a QA style interview Mention | Paris, FR | Take-home small exercise followed up by on site meetings with your future coworkers Mercatus | Toronto, Canada | Practical on-site project similar to daily work mfind | Warsaw, PL | Phone call about technical experience, Take-home project or technical test(depends on experience), Onsite interview with technical lead. miDrive | London, UK | Phone screen, Take-home project / technical test, Onsite interview with senior and peer. milch & zucker | Gießen, Germany | Interview with direct feedback, applicants providing working sample, code review (product code or personal code of applications) Mimir | Indianapolis, Indiana | Take home interview, phone screen, in person interview where you decide how you want to be interviewed (questions, pair programming, etc.) Minute Media | Tel-Aviv, Israel | Phone screening with engineer. On-site real-world challenge questions with two engineers. Sometimes a take-home assignment or existing code sample submission. Mirumee | Wroclaw, Poland; Remote | Pair programming and code review using one of the issues (or Pull Requests) in our open-source Saleor project, general discussion about programming, technology and candidate's experience Mixmax | San Francisco, CA | Takehome assignment purely based on their platform, followed by phone interview MobileCashout | Barcelona, Spain; Valencia, Spain | Quick introduction video call with a tech (less than 10-15 minutes). On-site open source contribution to a project of candidates choosing, paired with a tech from the team. Interview and a short questionaire about software design and relevant technologies. Interview and presentation of the company with a HR rep. Mobilethinking | Geneva, Switzerland | 1 hour discussion about technical background and past experiences, preferably in-person Mode | San Francisco, CA | Phone interview followed by onsite pair-architecting and discussion MokaHR | Beijing, China | Take home project/challenge, then on-site programming session taken from problems we encounter at work Moneytree Front-end Web Team | Tokyo, Japan | Pair programming exercise and social gathering with team Monzo | London, UK & Remote | Phone interview with another engineer. Take-home assignment. Call to debrief on take-home assignment. Half-day interview (on-site or Hangouts) with three conversational sessions: (1) building on take-home test & real-world system design (verbal and collaborative); (2) digging into knowledge & understanding in 1-2 other relevant technical areas; (3) general background, teams and ways of working. Moteefe | London, UK & Remote | Interview with CTO. Take home project/challenge. Mutual Mobile | Austin, TX; Hyderabad, India | Technical discussion, code test based on actual work you'll be doing, panel style discussions for cross-functional and culture-fit. Mutual of Omaha | Omaha, NE, USA | Panel Style Interviews analyzing problem solving, ability to adapt well to change, and interpersonal communication skills. Mutually Human Software | MI, OH, WA | Collaborative problem analysis and design exercise, pairing exercise Nanobox | Lehi, UT; Remote | A phone/video/person-to–person interview with a look at past projects (github, bitbucket, source code, etc.) Native Instruments | Berlin, Germany | Takehome programming assignment and personal interviews with part of the hiring team. Nearsoft Inc | Hermosillo, Mexico; Chihuahua, Mexico; Mexico City, Mexico | Takehome logic test, english interview to check communication skills, short technical interview about experience, long technical discussion about languages/tools/practices you will use on daily basis, pair programming session. Nedap | Groenlo, Netherlands / Remote | A simple conversation, human to human and a small on-site project Neoteric | Gdańsk, Warsaw Poland; Remote | Face2Face conversation, take home exercise & pair programming session Netflix | Los Gatos, CA | Takehome exercise, series of real-world interviews with engineers, HR, engineering managers and our director Netguru | Warsaw, Poland; Remote | Takehome exercise & pair programming session Netlandish | Los Angeles, CA; Remote | Takehome exercise, chat interview, video interview Netlify | San Francisco, CA | Paid takehome project and online/onsite discussion New Relic | San Francisco, CA | Takehome exercise &/ or pair programming session depending on the team NewStore | Berlin, Germany; Hannover, Germany; Erfurt, Germany; Boston, MA | Telephone technical interview, code sample submission or takeaway coding exercise, on-site pair programming, design session (1/2 day) NewVoiceMedia | Basingstoke, England; Wroclaw, Poland | Telephone interview, takeaway coding exercise, on-site pair programming, code review & technical discussion (1/2 day) Nexcess.net | Southfield, MI | We mostly chat to get a feel on both ends if there's a good cultural fit. We ask questions to see what experience you have and how you think as a programmer. At some point we look at some of your code or have you work on some of ours (1 hour). Nimbl3 | Bangkok, Thailand | Takehome exercise and specific role discussion Niteoweb | Ljubljana, Slovenia | Join us for a week to see if we fit Nitro | Dublin, Ireland; San Francisco, CA | Phone Call, Take Home Test, Hiring Manager Phone Interview followed by an onsite discussion Noa | Berlin, Germany; San Francisco, CA | 1 technical chat, 2-3 cultural chats with colleagues from different departments in the team, if these work a pair programming exercise NodeSource | Remote | A person-to–person walk through of a past project of yours Nomoko,camera | Zurich, Switzerland | Three interrogations Nord Software | Helsinki, Finland; Tampere, Finland; Stockholm, Sweden | Take-home exercise & interview with CEO and senior developer NoRedInk | San Francisco, CA | Take-home exercise & pair programming session NoviCap | Barcelona, Spain | Takehome exercise & discussion on-site Novoda | London, UK; Liverpool, UK; Berlin, Germany; Barcelona, Spain; Remote | 2 x Pairing sessions & conversational interviews (public repo) Novus Partners | New York, NY | Take-home exercise & on-site exercises (choice of laptop or whiteboard) Nozbe | Remote | Take-home exercise & interview with the team npm, Inc | Oakland, CA / Remote | No technical challenges. Just interview conversations. Nubank | São Paulo, BR | Phone conversation, take-home exercise, code walkthrough, on-site code pairing. numberly | Paris, France | Series of interviews, that go over technical background, past experiences and cultural knowledge numer.ai | San Francisco, CA Nutshell | Ann Arbor, MI, US | Email screen / take-home programming excercise ( public repo) Nyon | Amsterdam, The Netherlands | 1. Skype (or real life) interview 2. Take home exercise (3-4 hours) 3. Meet entire team and pair programming sessions O'Reilly Media | Sebastopol, CA; Boston, MA; Remote | Phone conversation, take-home exercise or pair programming session, team interview, all via Google Hangout Object Partners, Inc. | Minneapolis, MN; Omaha, NE | Phone interview to gauge mutual interest, followed by a slightly more in-depth technical round-table interview Objective, Inc. | Salt Lake City, UT | Take-home programming exercise, then onsite friendly chat with team OCTO Technology | Paris, France | HR interview to go over your experiences and cultural knowledge. Then more or less informal discussion with two future team members about architecture design, agile practices, take-home project, pair programming... Olist | Curitiba, Brazil | Take-home project and remote or on-site interviews Omada Health | San Francisco, CA | Take home exercise and/or pair programming session. Onfido | London, UK; Lisbon, Portugal | Take-home exercise and on-site interview/discussion with potential team Ontame.io | Copenhagen, Denmark | Take home exercise and specific role discussion Opbeat | Copenhagen, Denmark | Pairing on a real-world problem Openmind | Monza, Italy | On-site interviews Optoro | Washington, DC | Take home exercise. Review your code onsite. Ostmodern | London, UK | Take-home exercise & discussion on-site Outbrain | NYC, Israel | Take-home exercise & discussion Outlandish | London, UK | Take-home exercise, real-world pair programming session, friendly chat with team Outlook iOS & Android | San Francisco, CA / New York, NY | Take-home project & online / onsite discussion The Nerdery | Minneapolis, MN; Chicago, IL; Phoenix, AZ; Kansas City, KS | Take-home exercise The Outline | New York, NY | Take-home exercise P - R PACE Telematics | Karlsruhe, Germany | Culture and mindset check, on-site meet and great, small code challenge to see development style and strategy Paessler AG | Nuremberg, Germany | Pairing with different engineers on a real problem Pagar.me | São Paulo, BR | Skype interview, on-site pairing task and-or real world problem solving process / presentation Pager | New York, NY; Remote | Short phone interview, conversational interviews, take-home exercise & discussion PagerDuty | San Francisco, CA / Toronto, Canada / Atlanta, GA | Zoom / on-site pair programming and tasks Palatinate Tech | London, UK | Hangout/Skype/phone followed by (normally) on-site pairing task Parabol | New York, NY; Los Angeles, CA; Remote | Culture check followed by compensated, open-source contribution skills evaluation Pariveda Solutions | Dallas, TX / Houston, TX / Atlana, GA / Washington, DC / New York, NY / Chicago, IL / San Francisco, CA / Seattle, WA / Los Angeles, CA | Personality assessment (Predictive Index) and case study. Programming aptitude test (language independent) for college hires. PassFort | London, UK | Skype interview, and on-site pairing task Paws | London, UK | Phone screening, take-home project, on-site pairing/discussion on your solution and meet the team. Paybase | London, UK | Phone screening, Take home project, On-site interview for technical and culture fit, Open Q&A session with team PayByPhone | Vancouver, Canada | Remote programming interview, on-site "meet the team" Peaksware Companies (TrainingPeaks, TrainHeroic, MakeMusic) | Boulder, CO; Denver, CO | Phone screen, take home project, remote and on-site interviews for technical and cultural fit PeerStreet | Los Angeles, CA | Phone, take home project & on-site to meet the team Pento | Remote | Quick personal interview, take home project Persgroep, de | Amsterdam, Netherlands | Tech interview (technical background and experiences) and culture fit, both on-site Pex | Los Angeles, CA; Remote | 3 sessions: brief phone conversation (30 min); take home assignment (2 hours); on-site or video discussion without any coding (2 hours) Phoodster | Stockholm, Sweden | Take-home exercise + on-site discussion Pillar Technology | Ann Arbor, MI; Columbus, OH; Des Moines, IA | Phone, take home exercise, in-person pairing session and site visit. Pilot | Remote | Two calls. Introduction one (30m) + verification of communication skills and remote work experience (15m) Pivotal | San Francisco, CA; Los Angeles, CA; New York, NY; Boston, MA; Denver, CO; Atlanta, GA; Chicago, IL; Seattle, WA; Washington, D.C.; London, UK; Sydney, Australia; Toronto, Canada; Paris, France; Berlin, Germany; Tokyo, Japan | Initial remote technical screen featuring pair programming; on-site pair programming interview, generally a full day pairing on production code using test-driven development. Platform.sh | Paris, International | Remote Interview, Wide-Ranging discussions on many diverse subjects. Remote interviews with team members. Platform45 | Johannesburg, South Africa; Cape Town, South Africa | On-site interview, take-home project and culture fit day Playlyfe | Bangalore, India | Short personal interview, on-site demonstration of programming in browser devtools followed by discussion about the problem Pluralsight | Salt Lake City, UT; San Francisco, CA; Boston, MA; Orlando, FL | Takehome exercise & pair programming session Pointman | Buffalo, NY | Takehome exercise + on-site discussion Poki | Amsterdam, The Netherlands | Pair programming on-site w/ two engineers where we focus on teamwork, googling relevant documentation and fixing things together. Polar | Toronto, Canada | Phone interview, followed by 1-2 onsite pair-programming interviews based on their platform Popstand | Los Angeles, CA | Build MVPs for startups Popular Pays | Chicago, IL | Phone chat/coffee to determine what will be worked on during a day of pair-programming on a real problem that the candidate thinks best demonstrates their skills. Pragmateam | Sydney, Australia | Engineering Consultancy And Delivery - Takehome exercise & discussion PremiumBeat | Montreal, Canada | Discussion and general, high level questions Primary | New York, NY / Remote | Phone chat, take home exercise, pair program and discuss onsite. PromptWorks | Philadelphia, PA | Take-home project, pair programming, discussion on-site Pusher | London, UK | Solve a real-world problem through a design session with our engineers Pygmalios | Bratislava, Slovakia | Take-home project related to business and discussion with our engineers. Quiet Light Communications | Rockford, IL, USA | Discussion, work samples and/or small freelance project Quintype | Bengaluru, India / San Mateo, USA | Take home project, pair programming, discussion on-site Quizizz | Bengaluru, India | Phone chat, real world assignment, discussion w/ developers, pair programming, discussion on-site Ragnarson | Lodz, Poland; Remote | Take-home exercise & pair programming session Railslove | Cologne, Germany | Have a coffee in our office, casual chat with us, pair programming on a real project Raising IT | London, UK | Coffee with a team member, on-site pair programming and discussion Rakuten | Tokyo, Japan | Discuss about relevant experience Rapyuta Robotics | Bengaluru, India / Tokyo, Japan / Zurich, Switzerland | Take-home assignment related to our ongoing projects, series of technical / experience based interviews, candidate presentation Rayfeed | Vancouver, Warsaw | Video-call interview followed by a take-home exercise Razorpay | Bangalore, India | Phone screen, On-site pair programming, and ocassionally a take home project. ReactiveOps | Remote | Start with a brief talk with CTO or VP of Engineering, take home coding challenge, then remote interviews with several people on the engineering team Reaktor | New York, NY; Amsterdam, Netherlands; Helsinki, Finland; Tokyo, Japan | Discussion, work samples from previous projects (work or hobby), take-home exercise if needed for further info Real HQ | Austin, TX / Chicago, IL / Remote | Phone/video interviews, a take-home coding exercise, and a remote pair programming session. Realync | Chicago, IL / Carmel, IN / Remote | Quick phone interview, then a take home project and finally in person interview (open discussions instead of quizzes - anything technical are real-world problems). Red Badger | London, UK | Phone & Skype interview, take home exercise, On-site interview RedCarpet | New Delhi, India | Interview, work sample/take-home project and discussion/code reviews Reflektive | San Francisco, CA; Bengaluru, India | A short take home project/assignment, followed by a couple of technical and non-technical discussions online and offline. Relabe | San Juan, PR | First we screen for cultural fit then check for technical proficiency. 2-3 Interviews max in SJ Rentify | London, UK | Phone call, take home real-world project, on-site pair programming, product discussion RentoMojo | Bangalore, India | Short takehome project + phone interview Resin.io | Remote | Take home real-world project and a couple of technical and non-technical discussions ReSpark | London, UK | Phone conversation followed by on-site interview w/ task relevant to daily role. RestaurantOps | Scottsdale, AZ | Take Home Project & pair programming session Revlv | Manila, Philippines | Discussion about developer skills, previous projects and experiences. Rex Software | Brisbane, Australia | Take home project, feedback + interview Rizk.com | Ta' Xbiex, Malta | Take-home assignment, discussion w/ developers Rockode | Bangalore, India | Real world assignment, group hack session, discussions Rose Digital | New York, NY | Phone conversation followed by pair coding components that mirror day to day work, in person discussion about code, take home project if needed for more info RubyGarage | Dnipro, UA | Take-home project, code review and discussion on-site Runtastic | Linz, Austria; Vienna, Austria | Video call with recruiting staff, take home project, video call for code review, discussion, questions S - U Sahaj Software Solutions | Bangalore, India; Chennai, India; San Jose, CA | Take home code + Pairing + Discussion Salesforce.org Tech & Products | Remote | Phone screen, hands-on programming test solving real-world problems, Google Hangouts video sessions with engineers Salesloft | Atlanta, GA | Phone interview, take-home project, cultural-fit interview, technical interview where candidate modifies take-home project Samsara | San Francisco, CA; Atlanta, GA; London, UK | Phone interview, onsite interview (technical challenges based on real problems we've faced at Samsara) SC5 Online | Helsinki, Finland; Jyväskylä, Finland | Take-home assignment (intentionally short, takes at most an hour to complete), discussion and review assignments Segment | San Francisco, CA; Vancouver, Canada | Phone interview, take-home assignment (small fun project), onsite interview (technical + core/culture) -> intended to set you up for success Sensor Tower | San Francisco, CA | Phone call, on-site interview including discussion about projects/skills and a short real-world programming challenge Sensu | Remote | Video call, choice of pairing session or take home programming assignment Séntisis | Madrid, Spain; Mexico City, Mexico; Bogotá, Colombia; Santiago de Chile, Chile; Remote | Phone call, on-site/remote interview including discussion about projects/skills and a short real-world pair-programming exercise SerpApi | Austin, TX / Remote | Skype core value and culture interview, review of contributions on GitHub or other platforms, and take-home project if online contributions are not enough. Sertis | Bangkok, Thailand | Technical & culture fit interview, take-home project, follow-up discussion Setapp Sp. z o.o. | Poznan, Poland | Online/face-to-face discussion with developers about everyday programming dilemmas & reviewing your own code Sharoo | Zurich, Switzerland; Remote | Soft skills interview, take home project, technical interview based on take home project. Shogun | Remote | Discussion about software development and past experience, code samples, paid trial period. Showmax | Beroun, Czechia; Prague, Czechia; Remote | Take home project, then a pair-programming and discussion onsite / Hangouts round. ShuttleCloud | Chicago, IL / Madrid, Spain | Take-home project, then on-site code walk through and a real world problem discussion. Signal AI | London, UK | Phone screen; take home code exercise; on-site code extension with pair programming and discussion Simple | Portland, OR | Discussion about software development and architecture skills and experience. Simpli.fi | Fort Worth, TX, USA | Takehome code challenge and review SimpliField | Lille, France | Interview with the CTO and the developer team Simply Business | London, UK / Remote | Three stage, one day interview with quick feedback. One of the stages is 1.5h pair-programming session, where interviewee is assigned a task and interviewing developer plays role of Product Owner. Skyrise Pro | Chicago, IL | Take-home coding project, on-site interview including coding enhancements to the take-home project, offsite group activity Slack | San Francisco, CA | Call with recruiter, 1 week take-home project, call with hiring manager, on-site interview covering high-level system design, best software development practices and culture-fit Small Improvements | Berlin, Germany Social Tables | Washington, DC | Chat about skills and past experiences + bring in a code sample from previous work or side project to discuss SocialCops | New Delhi, India | A mini project (to be done within 8 days), followed by a discussion with the team you're applying to. Then as the final step, a call with one of the founders. Softwear | Amsterdam, Netherlands | Writing software for the fashion industry – remotely – in an international team. Sogilis | Grenoble, France | Discussion about interests, practices, and motivation. Presentation/code review/pair programming on a personal or professional project. Sourcegraph | San Francisco, CA & Remote | Tailored to the candidate, often consists of take-home work, discussion of real-world eng challenges, and product familiarity. Splice | New York, NY; Remote | Call with recruiter, 4 hr take-home project, video interview w two engs on take-home exercise, video call with hiring manager, video call w VPE & principal eng to talk about architecture. Spreedly | Durham, NC | Take-home project related to business Springer Nature (Asia) | Tokyo, Japan | Discussion & Pair programming session Springer Nature Digital | Berlin, Germany; London, UK | Phone chat; take-home project; then a pairing session based on the project, a technical chat, and a chat with non-technical team members SpronQ | Amsterdam, Netherlands | Takehome coding challenge Square | San Francisco, CA | Pair programming in a work environment Srijan Technologies | Delhi, India | General high level questions/discussion followed by Pair programming OR take-home coding challenge Stardog Union | Washington, DC; Remote | Technical discussion and general interest conversations Statflo | Toronto, Canada | Phone screening, take home project, on-site interview discussing the take home project, high-level architectural brainstorm, and questions about career and team work. store2be | Berlin, Germany | Skype/on-site interview, take-home project Storm | Seattle, WA; Remote | Phone/skype screen --> Take-home coding assignment --> on-site/skype interview loop to discuss assignment; meet-and-greet with other teams --> +1/-1 based on team consensus STYLABS | Mumbai, India | Phone Screen, Take-home project and discussion on-site Subvertical (VerticalChange) | Remote | Phone screening, live pair programming & personal project code review Sulvo | New York, NY / Remote | Interview over video call for cultural fit first, if you pass we proceed with technical interview that doesn't include coding games or challenges Superplayer | Porto Alegre, Brazil | Skype/On-site interview, take-home project and interview with CTO and CEO SurveySparrow | Kochi, India | Skype interview, take home project and code review, interview with CTO and CEO SVTi (Sveriges Television) | Stockholm, Sweden | On-site interview, take-home project, follow up interview where you walk through how you chose to solve the task. SweetIQ | Montreal, Canada | Discussion and general, high level questions Symphony Commerce | San Francisco, CA / Remote | Take-home project (phone), design discussion, review and critique our code, debugging questions Symplicity | Arlington, VA | Take-home project and code review in-person SysGarage | Buenos Aires, Argentina | Take-home project and real world pair programming TableCheck | Tokyo, Japan | Show us your code! Brief Skype interview and take-home project or pairing for those without code. Tailor Brands | Tel Aviv-Yafo, Israel | Discuss knowledge and interests, explore previous work experience, during the technical interview we discuss real-life problems. tails.com | Richmond (London), UK | Live pair programming or take home project with review Tanooki Labs | New York, NY | Paid half-day take home project with followup review and discussion Tattoodo | Copenhagen, Denmark | Takehome exercise Telus Digital | Toronto, Canada; Vancouver, Canada | Discuss knowledge and interest, explore previous work, pair with developers when possible, alternatively take home project. Ten Thousand Coffees | Toronto, Canada | Take home project, then explain how you solved the project Tes | Remote; London, UK | Remote pair programming session on React/Node kata with small takehome exercise as prep. Remote interview with senior engineers about previous experience, technical knowledge and interests. Tesco PLC | London, United Kingdom | Pair programming and casual hypothetical system design discussion Test Double | Remote | Initial conversation, Consulting interview, Technical interview, Pair programming, Takehome exercise. Textio | Seattle, WA | Initial screen to discuss experience and interest in a role at Textio; then a take-home programming task is discussed during a 1-hour tech screen (on-site or remote); finally a larger take-home project, simulating real work, is discussed during an on-site presentation plus 1-1s; How we hire The Book of Everyone | Barcelona, Spain | Quick interview, meet the team, pairing with developers on your own project theScore | Toronto, Canada | Coding challenge & systems design challenge Thinkmill | Sydney, Australia | Initial meet and greet interview with Thinkmillers from the relevant team, take home assignment followed by tech review on a followup interview. Thinslices | Iasi, Romania | Takehome exercise & in person pair programming on a simple Kata. thoughtbot | San Francisco, CA; London, UK | Our interview process ThoughtWorks | San Francisco, CA | Interviews with ThoughtWorkers of diverse backgrounds and roles; take home assignment followed by in person pairing session. Thread | London, UK | Take home test, real world architecture design, real world pair programming. ThreatSpike Labs | London, UK | Take home computing and security related challenges to be completed over a week. Tilde | Portland, OR | Pair programming sessions with each member of the team, working on problems similar to daily work. Timbuktu | Cape Town, South Africa | On site interview and pair programming exercise Titanium | Moldova, Chisinau | High level review of public activity on GitHub/BitBucket/Gitlab (if applicable) and screening via phone, On-site technical & Team fit interview, Formal "Meet the Team" meeting Toggl | Remote / Tallinn, Estonia | Online test on basic programming skills, followed by interview (typically includes get-to-know questions and technical skill testing). Depending on the team, there may be a take-home or live coding assignment. Paid test week to work with the team on actual bugs/features. Torii | Raanana, Israel | Take-home fun full-stack-app exercise followed by an on-site review Toucan Toco | Paris, France | Pair-programming and TDD Touché | Singapore, Singapore; Barcelona, Spain | Skype / Phone / on-site interview, take-home project, technical interview to discuss the project, team interview. TrademarkVision | Brisbane, Australia | On site interview and quick take-home excercise TrainHeroic | Boulder, CO; Denver, CO | Phone screen, take home project, remote and on-site interviews for technical and cultural fit TrainingPeaks | Boulder, CO; Denver, CO | Phone screen, take home project, remote and on-site interviews for technical and cultural fit TripStack | Toronto, Canada | Take-home assignment, followed up by a face to face code walk through Trivago | Düsseldorf, Germany | Case Study, Skype Interview, On site Interview with some code review exercises Trōv | Remote | Take-home project with followup interview from actual prospective teammates Truefit | Pittsburgh, PA | Phone screen, Take-home project, In-person interview with the team that you would join Truora | Bogotá, Colombia; Cali, Colombia; Remote | Take-home project, followed by phone interview with tech leads to discuss the project. Truss | San Francisco, CA; Remote | Phone screen/ Take-home project that resembles a problem Truss has seen many times before / Followup interview about the project / Closing Interview, all interviews done remotely Twistlock | Tel Aviv, Israel | Takehome uberall | Berlin, Germany | 30-min coding on-site, then a trial day uBiome | San Francisco, CA / Santiago, Chile | High level screening over the phone or on-site, take home project, code review and discussion Ubots | Porto Alegre, Brazil | Skype/On-site interview, take-home project, technical interview Unbounce | Vancouver, BC | Phone screen, take-home project, project discussion, technical interview Unboxed | London, UK | Take home feature requests, pairing with developers to extend solution, team-fit interviews, chat with a director Unearth | Seattle, WA | Take home project, team-fit interviews, technical discussion Unito | Montreal, Canada | Team-fit interviews, technical discussion, take home project Untappd | Wilmington, NC; New York, NY; Los Angeles, CA | Review portfolio - What projects have you worked on? + personality assessment, + interview Updater | New York, NY | Begin-at-home assignment highly relevant to role, presented and discussed during on-site. Uprise | Uppsala, Sweden | Take-home assignment, code review and discussion on-site Urban Massage | London, UK | Project done at home, in-person walk through. Meeting the team is an integral part. UserTesting | Atlanta, GA; San Francisco, CA; Mountain View, CA | Initial interview, pair programming, and offer uSwitch | London, UK | Take-home project related to our business area, followed by pairing with developers to extend it V - X Valassis Digital | Seattle, WA; San Francisco, CA; Lansing, MI; Hamburg, Germany | Phone screen, on-site interview with group, paired whiteboard problem solving and discussion, take-home project and follow-up review Valuemotive | Helsinki, Finland | Code examples from previous projects (work or hobby) or take-home exercise Varsity Tutors | Remote | Take home assignment, presentation of assignment, live code review with team. Advanced / high-level chat with team based on skillset and role. Vayu Technology | Sydney, Australia; Kathmandu, Nepal | Short interview, general programming questions and short take home challenge. Venminder, Inc. | Elizabethtown, KY; Louisville, KY | Initial phone screen to explain position. If candidate interested they get a take home assignment followed by a non-scripted in-person interview with team members to judge personality fit. Verve | London, UK | An intentionally short, take home exercise that mirrors real project work and incorporates code review elements Vingle | Seoul, Korea | Written interview, takehome project, in-person, conversational code review and interviews with engineers and engineering managers virtual7 | Kalrsruhe, Germany | Phone interview and on-site interview based on personal experience. Visma e-conomic | Copenhagen, Denmark | Take home assignment, assignment presentation and discussion Voltra Co. | Amsterdam, Netherlands / New York, NY / Remote | Show us your github account, tell us what you know. Let's pair on an OSS PR! VSX | Dresden, Germany | On-site interview, home coding challenge, presentation/discussion of proposed solutions VTEX | Rio de Janeiro, Brazil | Take-home project, Skype interview and then in-person talk. VTS | New York City, New York | Technical Phone Screen, Pair programming on-site & in-person talks with multiple engineers Waymark | Detroit, MI | Technical phone screen, take-home project, going over the project in person, follow up day in the office Wealthsimple | Toronto, Canada | Pair programming on a problem similar to daily work, discussion of system design WeAreHive | London, UK | Just walk us through your best code or we give you a small real-world exercise to do at home. Webantic | Manchester, UK | Basic TNA self-assessment and real-world problem-solving Webflow | San Francisco, CA & Remote | Short take-home challenge, followed by a paid 3-5 day freelance contract project Weebly | San Francisco, CA; Scottsdale, AZ; New York, NY | Phone screens (30 min to 1 hour) by a recruiter, an engineering manager (focused on your past experiences), an engineer (focused on system / db / api design). Followed by a paid 3 day onsite where you work on a project and then present it to a team of engineers. Weedmaps | Irvine, CA; Denver, CO; Tucson, AZ; Madrid, Spain; Remote | Phone screen, Group interview, and possible code review wemake.services | Remote | Short unpaid take-home challenge, code review, portfolio discussion Weploy | Melbourne, Australia; Sydney, Australia | Phase 1: Face to face interview to get to know the candidate. Phase 2: Problem solving session that involves designing a solution to a real-world problem followed by 1/2 day of pairing with a senior dev on implementing the proposed solution. WeTransfer | Amsterdam, Netherlands | Culture fit and fundamentals chat, skills interview - no whiteboarding! - and take-home project, communication and collaboration interview, meet with the VP of Engineering Wheely | Moscow, Russia | Get to know each other in under 30 minutes on-site or via Skype, take-home challenge, on-site review and interview with the team. Wildbit | Philadelphia, PA & Remote | Take-home project followed by interviews. Wirecard Brasil | São Paulo, Brazil | Phone or on-site Cultural Fit interview, take-home coding challenge, code review and discussing in-person. WorldGaming | Toronto, Canada | Technical Interview, Solution Design, Take Home Assignment, then Culture fit interview with the team woumedia | Remote | Getting to know each other and aligning expectations. Talking about past experiences, projects you are proud of and latest challenges you faced. It's followed by a use case study from one of our current projects. WyeWorks | Montevideo, Uruguay | Take-home project and discussion on-site X-Team | Remote | A short, fun Node.js challenge, followed by a series of culture-based interview questions, followed by a creative mock project with tons of freedom on how to approach, and follow-up questions about the approach they chose to discuss the tradeoffs. Usually a 10-30 day paid training is rewarded to top candidates to prep them for remote communication skills needed to join a team. XING | Hamburg, Germany | Take-home coding challenge, on-site review and short interviews with future team. Y - 1000mercis group | Paris, France | Series of interviews, that go over technical background, past experiences and cultural knowledge 18F | Remote; Washington, DC; New York, NY; Chicago, IL; San Francisco, CA | take-home coding exercise (2-4 hours), technical and values-match interviews over video chat 3D Hubs | Amsterdam, The Netherlands | Take-home code challenge from our product's domain followed by discussion remote/on-site, sometimes do an additional on-site pair programming session. 500friends | San Francisco, CA; Remote | Take home challenge followed by onsite expansion of the submission and high level discussions (design exercise or overview of past projects) 500Tech | Tel Aviv, Israel | Pair programming on a laptop in working env 8th Light | Chicago, IL; London, UK; Los Angeles, CA; New York, NY | Take home code challenge, discussion, pair programming session Yhat | Brooklyn, NY | Demo something cool you built and walk us thru the code + design decisions YLD | London, UK | Take home-code challenge, pair-programming session and discussion about past experience Yodas | Binyamina, Israel | Coding tasks over github repository Yoyo Wallet | London, UK | Take home code challenge, discussion of the code challenge, and general, high level questions YunoJuno | London, UK | Code challenge based on a realistic feature request on a real open-source package created and used at YunoJuno; phone/video interview with members of the Product team to explore technical background, experiences, interests, cultural fit; on-site interview, usually with Product Manager and CTO ZAP Group | São Paulo, Brazil | Takehome exercise, series of real-world interviews with engineers, HR, engineering managers and product managers on site. Zencargo | London, UK | Initial interview with CTO, covering professional experience interests and expectations, followed by one technical interview focused on fundamentals and familiarity with best practices. A further short chat with co-founders to get to know each other - - either onsite or remote. Zenefits (UI Team) | San Francisco, CA | One technical phone screen focused on JS fundamentals and/or one timeboxed take-home challenge. The onsite is a series of interviews designed to test your understanding of JS, HTML/CSS, design, etc. Zerodha | Bengaluru, India | Technical call at the beginning and one take home programming task. Zype | New York, NY & Remote | Skype/Video call with VP of Product and a take-home challenge.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Markdown Markdown: Why markdown? Markdown is a universal doc format that is easy to write and easy to add to a version control system. Open - Anyone can submit content, fix typos & update anything via pull requests Version control - Roll back & see the history of any given post No CMS lock in - We can easily port to any static site generator It's just simple - No user accounts to manage, no CMS software to upgrade, no plugins to install. Markdown basics The basics of markdown can be found here & here. Super easy! Advanced Formatting tips left alignment This is the code you need to align images to the left:<img align="left" width="100" height="100" src="http://www.fillmurray.com/100/100"> right alignment This is the code you need to align images to the right:<img align="right" width="100" height="100" src="http://www.fillmurray.com/100/100"> center alignment example<p align="center"> <img width="460" height="300" src="http://www.fillmurray.com/460/300"> </p> collapse Sections Collapsing large blocks of text can make your markdown much easier to digest"Click to expand" this is hidden block <details> <summary>"Click to expand"</summary> this is hidden </details> Collapsing large blocks of Markdown text To make sure markdown is rendered correctly in the collapsed section... Put an empty line after the <summary> block. Insert your markdown syntax Put an empty line before the </details> tag<details> <summary>To make sure markdown is rendered correctly in the collapsed section...</summary> 1. Put an **empty line** after the `<summary>` block. 2. *Insert your markdown syntax* 3. Put an **empty line** before the `</details>` tag </details> additional links Website • Email Updates • Gitter • Forum • Meetups • Twitter • Facebook • Contact Us[Website](http://www.serverless.com) • [Email Updates](http://eepurl.com/b8dv4P) • [Gitter](https://gitter.im/serverless/serverless) • [Forum](http://forum.serverless.com) • [Meetups](https://github.com/serverless-meetups/main) • [Twitter](https://twitter.com/goserverless) • [Facebook](https://www.facebook.com/serverless) • [Contact Us](mailto:hello@serverless.com) Badges I hate them so. Don't use badges. Nice looking file tree For whatever reason the graphql syntax will nicely highlight file trees like below:# Code & components for pages ./src/* ├─ src/assets - # Minified images, fonts, icon files ├─ src/components - # Individual smaller components ├─ src/fragments - # Larger chunks of a page composed of multiple components ├─ src/layouts - # Page layouts used for different types of pages composed of components and fragments ├─ src/page - # Custom pages or pages composed of layouts with hardcoded data components, fragments, & layouts ├─ src/pages/* - # Next.js file based routing │ ├─ _app.js - # next.js app entry point │ ├─ _document.js - # next.js document wrapper │ ├─ global.css - # Global CSS styles │ └─ Everything else... - # File based routing └─ src/utils - # Utility functions used in various places Useful packages gray-matter YAML front-matter is your friend. You can keep metadata in markdown files title: Serverless Framework Documentation description: "Great F'in docs!" menuText: Docs layout: Doc Remark Useful for rendering markdown in HTML/React Markdown Magic Repo Plugins Show automatic doc generation. Example 1 | Example 2 Useful utilities Schedule Posts - Post scheduler for static sites Show DEMO Zero friction inline content editing Show DEMO Byword & Typora - Good Editors Monodraw - Flow charts for days Kap - Make gifs IDE markdown preview Stuck on WordPress? Try easy-markdown plugin How Serverless uses markdown Serverless.com is comprised of 3 separate repositories https://github.com/serverless/blog https://github.com/serverless/serverless | Shoutout to Phenomic.io https://github.com/serverless/site Why multiple repos? We wanted documentation about the framework to live in the serverless github repo for easy access We wanted our blog content to be easily portable to any static site generator separate from the implementation (site) prebuild npm script pulls the content together & processes them for site build A single repo is easier to manage but harder for people to find/edit/PR content. DEMO Site structure Serverless build process Validation Editing Flow Github optimizations Link from top of each doc to live link on site use markdown magic =) to auto generate tables etc Hide yaml frontmatter from github folks consider linking everything to site Other Markdown Resources Verb - Documentation generator for GitHub projects ACSII docs - Markdown alternative
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    HTML SPEC HTML SPEC File an issue about the selected text Living Standard — Last Updated 29 October 2021 Table of contents 1 Introduction 2 Common infrastructure 3 Semantics, structure, and APIs of HTML documents 4 The elements of HTML 5 Microdata 6 User interaction 7 Loading web pages 8 Web application APIs 9 Communication 10 Web workers 11 Worklets 12 Web storage 13 The HTML syntax 14 The XML syntax 15 Rendering 16 Obsolete features 17 IANA considerations Index References Acknowledgments Intellectual property rights Full table of contents 1 Introduction 1.1 Where does this specification fit? 1.2 Is this HTML5? 1.3 Background 1.4 Audience 1.5 Scope 1.6 History 1.7 Design notes 1.7.1 Serializability of script execution 1.7.2 Compliance with other specifications 1.7.3 Extensibility 1.8 HTML vs XML syntax 1.9 Structure of this specification 1.9.1 How to read this specification 1.9.2 Typographic conventions 1.10 A quick introduction to HTML 1.10.1 Writing secure applications with HTML 1.10.2 Common pitfalls to avoid when using the scripting APIs 1.10.3 How to catch mistakes when writing HTML: validators and conformance checkers 1.11 Conformance requirements for authors 1.11.1 Presentational markup 1.11.2 Syntax errors 1.11.3 Restrictions on content models and on attribute values 1.12 Suggested reading 2 Common infrastructure 2.1 Terminology 2.1.1 Parallelism 2.1.2 Resources 2.1.3 XML compatibility 2.1.4 DOM trees 2.1.5 Scripting 2.1.6 Plugins 2.1.7 Character encodings 2.1.8 Conformance classes 2.1.9 Dependencies 2.1.10 Extensibility 2.1.11 Interactions with XPath and XSLT 2.2 Policy-controlled features 2.3 Common microsyntaxes 2.3.1 Common parser idioms 2.3.2 Boolean attributes 2.3.3 Keywords and enumerated attributes 2.3.4 Numbers 2.3.4.1 Signed integers 2.3.4.2 Non-negative integers 2.3.4.3 Floating-point numbers 2.3.4.4 Percentages and lengths 2.3.4.5 Nonzero percentages and lengths 2.3.4.6 Lists of floating-point numbers 2.3.4.7 Lists of dimensions 2.3.5 Dates and times 2.3.5.1 Months 2.3.5.2 Dates 2.3.5.3 Yearless dates 2.3.5.4 Times 2.3.5.5 Local dates and times 2.3.5.6 Time zones 2.3.5.7 Global dates and times 2.3.5.8 Weeks 2.3.5.9 Durations 2.3.5.10 Vaguer moments in time 2.3.6 Colors 2.3.7 Space-separated tokens 2.3.8 Comma-separated tokens 2.3.9 References 2.3.10 Media queries 2.4 URLs 2.4.1 Terminology 2.4.2 Parsing URLs 2.4.3 Dynamic changes to base URLs 2.5 Fetching resources 2.5.1 Terminology 2.5.2 Determining the type of a resource 2.5.3 Extracting character encodings from meta elements 2.5.4 CORS settings attributes 2.5.5 Referrer policy attributes 2.5.6 Nonce attributes 2.5.7 Lazy loading attributes 2.6 Common DOM interfaces 2.6.1 Reflecting content attributes in IDL attributes 2.6.2 Collections 2.6.2.1 The HTMLAllCollection interface 2.6.2.1.1 [[Call]] ( thisArgument, argumentsList ) 2.6.2.2 The HTMLFormControlsCollection interface 2.6.2.3 The HTMLOptionsCollection interface 2.6.3 The DOMStringList interface 2.7 Safe passing of structured data 2.7.1 Serializable objects 2.7.2 Transferable objects 2.7.3 StructuredSerializeInternal ( value, forStorage [ , memory ] ) 2.7.4 StructuredSerialize ( value ) 2.7.5 StructuredSerializeForStorage ( value ) 2.7.6 StructuredDeserialize ( serialized, targetRealm [ , memory ] ) 2.7.7 StructuredSerializeWithTransfer ( value, transferList ) 2.7.8 StructuredDeserializeWithTransfer ( serializeWithTransferResult, targetRealm ) 2.7.9 Performing serialization and transferring from other specifications 2.7.10 Structured cloning API 3 Semantics, structure, and APIs of HTML documents 3.1 Documents 3.1.1 The Document object 3.1.2 The DocumentOrShadowRoot interface 3.1.3 Resource metadata management 3.1.4 Reporting document loading status 3.1.5 DOM tree accessors 3.2 Elements 3.2.1 Semantics 3.2.2 Elements in the DOM 3.2.3 HTML element constructors 3.2.4 Element definitions 3.2.4.1 Attributes 3.2.5 Content models 3.2.5.1 The "nothing" content model 3.2.5.2 Kinds of content 3.2.5.2.1 Metadata content 3.2.5.2.2 Flow content 3.2.5.2.3 Sectioning content 3.2.5.2.4 Heading content 3.2.5.2.5 Phrasing content 3.2.5.2.6 Embedded content 3.2.5.2.7 Interactive content 3.2.5.2.8 Palpable content 3.2.5.2.9 Script-supporting elements 3.2.5.3 Transparent content models 3.2.5.4 Paragraphs 3.2.6 Global attributes 3.2.6.1 The title attribute 3.2.6.2 The lang and xml:lang attributes 3.2.6.3 The translate attribute 3.2.6.4 The dir attribute 3.2.6.5 The style attribute 3.2.6.6 Embedding custom non-visible data with the data-* attributes 3.2.7 The innerText and outerText properties 3.2.8 Requirements relating to the bidirectional algorithm 3.2.8.1 Authoring conformance criteria for bidirectional-algorithm formatting characters 3.2.8.2 User agent conformance criteria 3.2.9 Requirements related to ARIA and to platform accessibility APIs 4 The elements of HTML 4.1 The document element 4.1.1 The html element 4.2 Document metadata 4.2.1 The head element 4.2.2 The title element 4.2.3 The base element 4.2.4 The link element 4.2.4.1 Processing the media attribute 4.2.4.2 Processing the type attribute 4.2.4.3 Fetching and processing a resource from a link element 4.2.4.4 Processing ` Link` headers 4.2.4.5 Providing users with a means to follow hyperlinks created using the link element 4.2.5 The meta element 4.2.5.1 Standard metadata names 4.2.5.2 Other metadata names 4.2.5.3 Pragma directives 4.2.5.4 Specifying the document's character encoding 4.2.6 The style element 4.2.7 Interactions of styling and scripting 4.3 Sections 4.3.1 The body element 4.3.2 The article element 4.3.3 The section element 4.3.4 The nav element 4.3.5 The aside element 4.3.6 The h1, h2, h3, h4, h5, and h6 elements 4.3.7 The hgroup element 4.3.8 The header element 4.3.9 The footer element 4.3.10 The address element 4.3.11 Headings and sections 4.3.11.1 Creating an outline 4.3.11.2 Sample outlines 4.3.11.3 Exposing outlines to users 4.3.12 Usage summary 4.3.12.1 Article or section? 4.4 Grouping content 4.4.1 The p element 4.4.2 The hr element 4.4.3 The pre element 4.4.4 The blockquote element 4.4.5 The ol element 4.4.6 The ul element 4.4.7 The menu element 4.4.8 The li element 4.4.9 The dl element 4.4.10 The dt element 4.4.11 The dd element 4.4.12 The figure element 4.4.13 The figcaption element 4.4.14 The main element 4.4.15 The div element 4.5 Text-level semantics 4.5.1 The a element 4.5.2 The em element 4.5.3 The strong element 4.5.4 The small element 4.5.5 The s element 4.5.6 The cite element 4.5.7 The q element 4.5.8 The dfn element 4.5.9 The abbr element 4.5.10 The ruby element 4.5.11 The rt element 4.5.12 The rp element 4.5.13 The data element 4.5.14 The time element 4.5.15 The code element 4.5.16 The var element 4.5.17 The samp element 4.5.18 The kbd element 4.5.19 The sub and sup elements 4.5.20 The i element 4.5.21 The b element 4.5.22 The u element 4.5.23 The mark element 4.5.24 The bdi element 4.5.25 The bdo element 4.5.26 The span element 4.5.27 The br element 4.5.28 The wbr element 4.5.29 Usage summary 4.6 Links 4.6.1 Introduction 4.6.2 Links created by a and area elements 4.6.3 API for a and area elements 4.6.4 Following hyperlinks 4.6.5 Downloading resources 4.6.5.1 Hyperlink auditing 4.6.6 Link types 4.6.6.1 Link type " alternate" 4.6.6.2 Link type " author" 4.6.6.3 Link type " bookmark" 4.6.6.4 Link type " canonical" 4.6.6.5 Link type " dns-prefetch" 4.6.6.6 Link type " external" 4.6.6.7 Link type " help" 4.6.6.8 Link type " icon" 4.6.6.9 Link type " license" 4.6.6.10 Link type " manifest" 4.6.6.11 Link type " modulepreload" 4.6.6.12 Link type " nofollow" 4.6.6.13 Link type " noopener" 4.6.6.14 Link type " noreferrer" 4.6.6.15 Link type " opener" 4.6.6.16 Link type " pingback" 4.6.6.17 Link type " preconnect" 4.6.6.18 Link type " prefetch" 4.6.6.19 Link type " preload" 4.6.6.20 Link type " prerender" 4.6.6.21 Link type " search" 4.6.6.22 Link type " stylesheet" 4.6.6.23 Link type " tag" 4.6.6.24 Sequential link types 4.6.6.24.1 Link type " next" 4.6.6.24.2 Link type " prev" 4.6.6.25 Other link types 4.7 Edits 4.7.1 The ins element 4.7.2 The del element 4.7.3 Attributes common to ins and del elements 4.7.4 Edits and paragraphs 4.7.5 Edits and lists 4.7.6 Edits and tables 4.8 Embedded content 4.8.1 The picture element 4.8.2 The source element 4.8.3 The img element 4.8.4 Images 4.8.4.1 Introduction 4.8.4.1.1 Adaptive images 4.8.4.2 Attributes common to source, img, and link elements 4.8.4.2.1 Srcset attributes 4.8.4.2.2 Sizes attributes 4.8.4.3 Processing model 4.8.4.3.1 When to obtain images 4.8.4.3.2 Reacting to DOM mutations 4.8.4.3.3 The list of available images 4.8.4.3.4 Decoding images 4.8.4.3.5 Updating the image data 4.8.4.3.6 Preparing an image for presentation 4.8.4.3.7 Selecting an image source 4.8.4.3.8 Updating the source set 4.8.4.3.9 Parsing a srcset attribute 4.8.4.3.10 Parsing a sizes attribute 4.8.4.3.11 Normalizing the source densities 4.8.4.3.12 Reacting to environment changes 4.8.4.4 Requirements for providing text to act as an alternative for images 4.8.4.4.1 General guidelines 4.8.4.4.2 A link or button containing nothing but the image 4.8.4.4.3 A phrase or paragraph with an alternative graphical representation: charts, diagrams, graphs, maps, illustrations 4.8.4.4.4 A short phrase or label with an alternative graphical representation: icons, logos 4.8.4.4.5 Text that has been rendered to a graphic for typographical effect 4.8.4.4.6 A graphical representation of some of the surrounding text 4.8.4.4.7 Ancillary images 4.8.4.4.8 A purely decorative image that doesn't add any information 4.8.4.4.9 A group of images that form a single larger picture with no links 4.8.4.4.10 A group of images that form a single larger picture with links 4.8.4.4.11 A key part of the content 4.8.4.4.12 An image not intended for the user 4.8.4.4.13 An image in an email or private document intended for a specific person who is known to be able to view images 4.8.4.4.14 Guidance for markup generators 4.8.4.4.15 Guidance for conformance checkers 4.8.5 The iframe element 4.8.6 The embed element 4.8.7 The object element 4.8.8 The param element 4.8.9 The video element 4.8.10 The audio element 4.8.11 The track element 4.8.12 Media elements 4.8.12.1 Error codes 4.8.12.2 Location of the media resource 4.8.12.3 MIME types 4.8.12.4 Network states 4.8.12.5 Loading the media resource 4.8.12.6 Offsets into the media resource 4.8.12.7 Ready states 4.8.12.8 Playing the media resource 4.8.12.9 Seeking 4.8.12.10 Media resources with multiple media tracks 4.8.12.10.1 AudioTrackList and VideoTrackList objects 4.8.12.10.2 Selecting specific audio and video tracks declaratively 4.8.12.11 Timed text tracks 4.8.12.11.1 Text track model 4.8.12.11.2 Sourcing in-band text tracks 4.8.12.11.3 Sourcing out-of-band text tracks 4.8.12.11.4 Guidelines for exposing cues in various formats as text track cues 4.8.12.11.5 Text track API 4.8.12.11.6 Event handlers for objects of the text track APIs 4.8.12.11.7 Best practices for metadata text tracks 4.8.12.12 Identifying a track kind through a URL 4.8.12.13 User interface 4.8.12.14 Time ranges 4.8.12.15 The TrackEvent interface 4.8.12.16 Events summary 4.8.12.17 Security and privacy considerations 4.8.12.18 Best practices for authors using media elements 4.8.12.19 Best practices for implementers of media elements 4.8.13 The map element 4.8.14 The area element 4.8.15 Image maps 4.8.15.1 Authoring 4.8.15.2 Processing model 4.8.16 MathML 4.8.17 SVG 4.8.18 Dimension attributes 4.9 Tabular data 4.9.1 The table element 4.9.1.1 Techniques for describing tables 4.9.1.2 Techniques for table design 4.9.2 The caption element 4.9.3 The colgroup element 4.9.4 The col element 4.9.5 The tbody element 4.9.6 The thead element 4.9.7 The tfoot element 4.9.8 The tr element 4.9.9 The td element 4.9.10 The th element 4.9.11 Attributes common to td and th elements 4.9.12 Processing model 4.9.12.1 Forming a table 4.9.12.2 Forming relationships between data cells and header cells 4.9.13 Examples 4.10 Forms 4.10.1 Introduction 4.10.1.1 Writing a form's user interface 4.10.1.2 Implementing the server-side processing for a form 4.10.1.3 Configuring a form to communicate with a server 4.10.1.4 Client-side form validation 4.10.1.5 Enabling client-side automatic filling of form controls 4.10.1.6 Improving the user experience on mobile devices 4.10.1.7 The difference between the field type, the autofill field name, and the input modality 4.10.1.8 Date, time, and number formats 4.10.2 Categories 4.10.3 The form element 4.10.4 The label element 4.10.5 The input element 4.10.5.1 States of the type attribute 4.10.5.1.1 Hidden state ( type=hidden) 4.10.5.1.2 Text ( type=text) state and Search state ( type=search) 4.10.5.1.3 Telephone state ( type=tel) 4.10.5.1.4 URL state ( type=url) 4.10.5.1.5 Email state ( type=email) 4.10.5.1.6 Password state ( type=password) 4.10.5.1.7 Date state ( type=date) 4.10.5.1.8 Month state ( type=month) 4.10.5.1.9 Week state ( type=week) 4.10.5.1.10 Time state ( type=time) 4.10.5.1.11 Local Date and Time state ( type=datetime-local) 4.10.5.1.12 Number state ( type=number) 4.10.5.1.13 Range state ( type=range) 4.10.5.1.14 Color state ( type=color) 4.10.5.1.15 Checkbox state ( type=checkbox) 4.10.5.1.16 Radio Button state ( type=radio) 4.10.5.1.17 File Upload state ( type=file) 4.10.5.1.18 Submit Button state ( type=submit) 4.10.5.1.19 Image Button state ( type=image) 4.10.5.1.20 Reset Button state ( type=reset) 4.10.5.1.21 Button state ( type=button) 4.10.5.2 Implementation notes regarding localization of form controls 4.10.5.3 Common input element attributes 4.10.5.3.1 The maxlength and minlength attributes 4.10.5.3.2 The size attribute 4.10.5.3.3 The readonly attribute 4.10.5.3.4 The required attribute 4.10.5.3.5 The multiple attribute 4.10.5.3.6 The pattern attribute 4.10.5.3.7 The min and max attributes 4.10.5.3.8 The step attribute 4.10.5.3.9 The list attribute 4.10.5.3.10 The placeholder attribute 4.10.5.4 Common input element APIs 4.10.5.5 Common event behaviors 4.10.6 The button element 4.10.7 The select element 4.10.8 The datalist element 4.10.9 The optgroup element 4.10.10 The option element 4.10.11 The textarea element 4.10.12 The output element 4.10.13 The progress element 4.10.14 The meter element 4.10.15 The fieldset element 4.10.16 The legend element 4.10.17 Form control infrastructure 4.10.17.1 A form control's value 4.10.17.2 Mutability 4.10.17.3 Association of controls and forms 4.10.18 Attributes common to form controls 4.10.18.1 Naming form controls: the name attribute 4.10.18.2 Submitting element directionality: the dirname attribute 4.10.18.3 Limiting user input length: the maxlength attribute 4.10.18.4 Setting minimum input length requirements: the minlength attribute 4.10.18.5 Enabling and disabling form controls: the disabled attribute 4.10.18.6 Form submission attributes 4.10.18.7 Autofill 4.10.18.7.1 Autofilling form controls: the autocomplete attribute 4.10.18.7.2 Processing model 4.10.19 APIs for the text control selections 4.10.20 Constraints 4.10.20.1 Definitions 4.10.20.2 Constraint validation 4.10.20.3 The constraint validation API 4.10.20.4 Security 4.10.21 Form submission 4.10.21.1 Introduction 4.10.21.2 Implicit submission 4.10.21.3 Form submission algorithm 4.10.21.4 Constructing the entry list 4.10.21.5 Selecting a form submission encoding 4.10.21.6 Converting an entry list to a list of name-value pairs 4.10.21.7 URL-encoded form data 4.10.21.8 Multipart form data 4.10.21.9 Plain text form data 4.10.21.10 The SubmitEvent interface 4.10.21.11 The FormDataEvent interface 4.10.22 Resetting a form 4.11 Interactive elements 4.11.1 The details element 4.11.2 The summary element 4.11.3 Commands 4.11.3.1 Facets 4.11.3.2 Using the a element to define a command 4.11.3.3 Using the button element to define a command 4.11.3.4 Using the input element to define a command 4.11.3.5 Using the option element to define a command 4.11.3.6 Using the accesskey attribute on a legend element to define a command 4.11.3.7 Using the accesskey attribute to define a command on other elements 4.11.4 The dialog element 4.12 Scripting 4.12.1 The script element 4.12.1.1 Processing model 4.12.1.2 Scripting languages 4.12.1.3 Restrictions for contents of script elements 4.12.1.4 Inline documentation for external scripts 4.12.1.5 Interaction of script elements and XSLT 4.12.2 The noscript element 4.12.3 The template element 4.12.3.1 Interaction of template elements with XSLT and XPath 4.12.4 The slot element 4.12.5 The canvas element 4.12.5.1 The 2D rendering context 4.12.5.1.1 Implementation notes 4.12.5.1.2 The canvas state 4.12.5.1.3 Line styles 4.12.5.1.4 Text styles 4.12.5.1.5 Building paths 4.12.5.1.6 Path2D objects 4.12.5.1.7 Transformations 4.12.5.1.8 Image sources for 2D rendering contexts 4.12.5.1.9 Fill and stroke styles 4.12.5.1.10 Drawing rectangles to the bitmap 4.12.5.1.11 Drawing text to the bitmap 4.12.5.1.12 Drawing paths to the canvas 4.12.5.1.13 Drawing focus rings and scrolling paths into view 4.12.5.1.14 Drawing images 4.12.5.1.15 Pixel manipulation 4.12.5.1.16 Compositing 4.12.5.1.17 Image smoothing 4.12.5.1.18 Shadows 4.12.5.1.19 Filters 4.12.5.1.20 Working with externally-defined SVG filters 4.12.5.1.21 Drawing model 4.12.5.1.22 Best practices 4.12.5.1.23 Examples 4.12.5.2 The ImageBitmap rendering context 4.12.5.2.1 Introduction 4.12.5.2.2 The ImageBitmapRenderingContext interface 4.12.5.3 The OffscreenCanvas interface 4.12.5.3.1 The offscreen 2D rendering context 4.12.5.4 Color spaces and color space conversion 4.12.5.5 Serializing bitmaps to a file 4.12.5.6 Security with canvas elements 4.12.5.7 Premultiplied alpha and the 2D rendering context 4.13 Custom elements 4.13.1 Introduction 4.13.1.1 Creating an autonomous custom element 4.13.1.2 Creating a form-associated custom element 4.13.1.3 Creating a custom element with default accessible roles, states, and properties 4.13.1.4 Creating a customized built-in element 4.13.1.5 Drawbacks of autonomous custom elements 4.13.1.6 Upgrading elements after their creation 4.13.2 Requirements for custom element constructors and reactions 4.13.3 Core concepts 4.13.4 The CustomElementRegistry interface 4.13.5 Upgrades 4.13.6 Custom element reactions 4.13.7 Element internals 4.13.7.1 The ElementInternals interface 4.13.7.2 Shadow root access 4.13.7.3 Form-associated custom elements 4.13.7.4 Accessibility semantics 4.14 Common idioms without dedicated elements 4.14.1 Breadcrumb navigation 4.14.2 Tag clouds 4.14.3 Conversations 4.14.4 Footnotes 4.15 Disabled elements 4.16 Matching HTML elements using selectors and CSS 4.16.1 Case-sensitivity of the CSS 'attr()' function 4.16.2 Case-sensitivity of selectors 4.16.3 Pseudo-classes 5 Microdata 5.1 Introduction 5.1.1 Overview 5.1.2 The basic syntax 5.1.3 Typed items 5.1.4 Global identifiers for items 5.1.5 Selecting names when defining vocabularies 5.2 Encoding microdata 5.2.1 The microdata model 5.2.2 Items 5.2.3 Names: the itemprop attribute 5.2.4 Values 5.2.5 Associating names with items 5.2.6 Microdata and other namespaces 5.3 Sample microdata vocabularies 5.3.1 vCard 5.3.1.1 Conversion to vCard 5.3.1.2 Examples 5.3.2 vEvent 5.3.2.1 Conversion to iCalendar 5.3.2.2 Examples 5.3.3 Licensing works 5.3.3.1 Examples 5.4 Converting HTML to other formats 5.4.1 JSON 6 User interaction 6.1 The hidden attribute 6.2 Inert subtrees 6.3 Tracking user activation 6.3.1 Data model 6.3.2 Processing model 6.3.3 APIs gated by user activation 6.4 Activation behavior of elements 6.5 Focus 6.5.1 Introduction 6.5.2 Data model 6.5.3 The tabindex attribute 6.5.4 Processing model 6.5.5 Sequential focus navigation 6.5.6 Focus management APIs 6.5.7 The autofocus attribute 6.6 Assigning keyboard shortcuts 6.6.1 Introduction 6.6.2 The accesskey attribute 6.6.3 Processing model 6.7 Editing 6.7.1 Making document regions editable: The contenteditable content attribute 6.7.2 Making entire documents editable: the designMode getter and setter 6.7.3 Best practices for in-page editors 6.7.4 Editing APIs 6.7.5 Spelling and grammar checking 6.7.6 Autocapitalization 6.7.7 Input modalities: the inputmode attribute 6.7.8 Input modalities: the enterkeyhint attribute 6.8 Find-in-page 6.8.1 Introduction 6.8.2 Interaction with details 6.8.3 Interaction with selection 6.9 Drag and drop 6.9.1 Introduction 6.9.2 The drag data store 6.9.3 The DataTransfer interface 6.9.3.1 The DataTransferItemList interface 6.9.3.2 The DataTransferItem interface 6.9.4 The DragEvent interface 6.9.5 Processing model 6.9.6 Events summary 6.9.7 The draggable attribute 6.9.8 Security risks in the drag-and-drop model 7 Loading web pages 7.1 Browsing contexts 7.1.1 Creating browsing contexts 7.1.2 Related browsing contexts 7.1.2.1 Navigating related browsing contexts in the DOM 7.1.3 Security 7.1.4 Groupings of browsing contexts 7.1.5 Browsing context names 7.2 Security infrastructure for Window, WindowProxy, and Location objects 7.2.1 Integration with IDL 7.2.2 Shared internal slot: [[CrossOriginPropertyDescriptorMap]] 7.2.3 Shared abstract operations 7.2.3.1 CrossOriginProperties ( O ) 7.2.3.2 CrossOriginPropertyFallback ( P ) 7.2.3.3 IsPlatformObjectSameOrigin ( O ) 7.2.3.4 CrossOriginGetOwnPropertyHelper ( O, P ) 7.2.3.5 CrossOriginGet ( O, P, Receiver ) 7.2.3.6 CrossOriginSet ( O, P, V, Receiver ) 7.2.3.7 CrossOriginOwnPropertyKeys ( O ) 7.3 The Window object 7.3.1 APIs for creating and navigating browsing contexts by name 7.3.2 Accessing other browsing contexts 7.3.3 Named access on the Window object 7.3.4 Discarding browsing contexts 7.3.5 Closing browsing contexts 7.3.6 Browser interface elements 7.3.7 Script settings for Window objects 7.4 The WindowProxy exotic object 7.4.1 [[GetPrototypeOf]] ( ) 7.4.2 [[SetPrototypeOf]] ( V ) 7.4.3 [[IsExtensible]] ( ) 7.4.4 [[PreventExtensions]] ( ) 7.4.5 [[GetOwnProperty]] ( P ) 7.4.6 [[DefineOwnProperty]] ( P, Desc ) 7.4.7 [[Get]] ( P, Receiver ) 7.4.8 [[Set]] ( P, V, Receiver ) 7.4.9 [[Delete]] ( P ) 7.4.10 [[OwnPropertyKeys]] ( ) 7.5 Origin 7.5.1 Sites 7.5.2 Relaxing the same-origin restriction 7.5.3 Origin-keyed agent clusters 7.6 Sandboxing 7.7 Cross-origin opener policies 7.7.1 The headers 7.7.2 Browsing context group switches due to cross-origin opener policy 7.7.3 Reporting 7.8 Cross-origin embedder policies 7.8.1 The headers 7.8.2 Embedder policy checks 7.9 Policy containers 7.10 Session history and navigation 7.10.1 Browsing sessions 7.10.2 The session history of browsing contexts 7.10.3 The History interface 7.10.4 Implementation notes for session history 7.10.5 The Location interface 7.10.5.1 [[GetPrototypeOf]] ( ) 7.10.5.2 [[SetPrototypeOf]] ( V ) 7.10.5.3 [[IsExtensible]] ( ) 7.10.5.4 [[PreventExtensions]] ( ) 7.10.5.5 [[GetOwnProperty]] ( P ) 7.10.5.6 [[DefineOwnProperty]] ( P, Desc ) 7.10.5.7 [[Get]] ( P, Receiver ) 7.10.5.8 [[Set]] ( P, V, Receiver ) 7.10.5.9 [[Delete]] ( P ) 7.10.5.10 [[OwnPropertyKeys]] ( ) 7.11 Browsing the web 7.11.1 Navigating across documents 7.11.2 Page load processing model for HTML files 7.11.3 Page load processing model for XML files 7.11.4 Page load processing model for text files 7.11.5 Page load processing model for multipart/x-mixed-replace resources 7.11.6 Page load processing model for media 7.11.7 Page load processing model for content that uses plugins 7.11.8 Page load processing model for inline content that doesn't have a DOM 7.11.9 Navigating to a fragment 7.11.10 History traversal 7.11.10.1 Persisted history entry state 7.11.10.2 The PopStateEvent interface 7.11.10.3 The HashChangeEvent interface 7.11.10.4 The PageTransitionEvent interface 7.11.11 Loading documents 7.11.12 Unloading documents 7.11.12.1 The BeforeUnloadEvent interface 7.11.13 Aborting a document load 7.11.14 The ` X-Frame-Options` header 8 Web application APIs 8.1 Scripting 8.1.1 Introduction 8.1.2 Agents and agent clusters 8.1.2.1 Integration with the JavaScript agent formalism 8.1.2.2 Integration with the JavaScript agent cluster formalism 8.1.3 Realms and their counterparts 8.1.3.1 Environments 8.1.3.2 Environment settings objects 8.1.3.3 Realms, settings objects, and global objects 8.1.3.3.1 Entry 8.1.3.3.2 Incumbent 8.1.3.3.3 Current 8.1.3.3.4 Relevant 8.1.3.4 Enabling and disabling scripting 8.1.3.5 Secure contexts 8.1.4 Script processing model 8.1.4.1 Scripts 8.1.4.2 Fetching scripts 8.1.4.3 Creating scripts 8.1.4.4 Calling scripts 8.1.4.5 Killing scripts 8.1.4.6 Runtime script errors 8.1.4.7 Unhandled promise rejections 8.1.5 JavaScript specification host hooks 8.1.5.1 HostEnsureCanCompileStrings(callerRealm, calleeRealm) 8.1.5.2 HostPromiseRejectionTracker(promise, operation) 8.1.5.3 Job-related host hooks 8.1.5.3.1 HostCallJobCallback(callback, V, argumentsList) 8.1.5.3.2 HostEnqueueFinalizationRegistryCleanupJob(finalizationRegistry) 8.1.5.3.3 HostEnqueuePromiseJob(job, realm) 8.1.5.3.4 HostMakeJobCallback(callable) 8.1.5.4 Module-related host hooks 8.1.5.4.1 HostGetImportMetaProperties(moduleRecord) 8.1.5.4.2 HostImportModuleDynamically(referencingScriptOrModule, moduleRequest, promiseCapability) 8.1.5.4.3 HostResolveImportedModule(referencingScriptOrModule, moduleRequest) 8.1.5.4.4 HostGetSupportedImportAssertions() 8.1.6 Event loops 8.1.6.1 Definitions 8.1.6.2 Queuing tasks 8.1.6.3 Processing model 8.1.6.4 Generic task sources 8.1.6.5 Dealing with the event loop from other specifications 8.1.7 Events 8.1.7.1 Event handlers 8.1.7.2 Event handlers on elements, Document objects, and Window objects 8.1.7.2.1 IDL definitions 8.1.7.3 Event firing 8.2 The WindowOrWorkerGlobalScope mixin 8.3 Base64 utility methods 8.4 Dynamic markup insertion 8.4.1 Opening the input stream 8.4.2 Closing the input stream 8.4.3 document.write() 8.4.4 document.writeln() 8.5 DOM parsing 8.6 Timers 8.7 Microtask queuing 8.8 User prompts 8.8.1 Simple dialogs 8.8.2 Printing 8.9 System state and capabilities 8.9.1 The Navigator object 8.9.1.1 Client identification 8.9.1.2 Language preferences 8.9.1.3 Browser state 8.9.1.4 Custom scheme handlers: the registerProtocolHandler() method 8.9.1.4.1 Security and privacy 8.9.1.5 Cookies 8.9.1.6 PDF viewing support 8.10 Images 8.11 Animation frames 9 Communication 9.1 The MessageEvent interface 9.2 Server-sent events 9.2.1 Introduction 9.2.2 The EventSource interface 9.2.3 Processing model 9.2.4 Parsing an event stream 9.2.5 Interpreting an event stream 9.2.6 Authoring notes 9.2.7 Connectionless push and other features 9.2.8 Garbage collection 9.2.9 Implementation advice 9.3 Web sockets 9.3.1 Introduction 9.3.2 The WebSocket interface 9.3.3 Feedback from the protocol 9.3.4 Ping and Pong frames 9.3.5 The CloseEvent interface 9.3.6 Garbage collection 9.4 Cross-document messaging 9.4.1 Introduction 9.4.2 Security 9.4.2.1 Authors 9.4.2.2 User agents 9.4.3 Posting messages 9.5 Channel messaging 9.5.1 Introduction 9.5.1.1 Examples 9.5.1.2 Ports as the basis of an object-capability model on the web 9.5.1.3 Ports as the basis of abstracting out service implementations 9.5.2 Message channels 9.5.3 Message ports 9.5.4 Broadcasting to many ports 9.5.5 Ports and garbage collection 9.6 Broadcasting to other browsing contexts 10 Web workers 10.1 Introduction 10.1.1 Scope 10.1.2 Examples 10.1.2.1 A background number-crunching worker 10.1.2.2 Using a JavaScript module as a worker 10.1.2.3 Shared workers introduction 10.1.2.4 Shared state using a shared worker 10.1.2.5 Delegation 10.1.2.6 Providing libraries 10.1.3 Tutorials 10.1.3.1 Creating a dedicated worker 10.1.3.2 Communicating with a dedicated worker 10.1.3.3 Shared workers 10.2 Infrastructure 10.2.1 The global scope 10.2.1.1 The WorkerGlobalScope common interface 10.2.1.2 Dedicated workers and the DedicatedWorkerGlobalScope interface 10.2.1.3 Shared workers and the SharedWorkerGlobalScope interface 10.2.2 The event loop 10.2.3 The worker's lifetime 10.2.4 Processing model 10.2.5 Runtime script errors 10.2.6 Creating workers 10.2.6.1 The AbstractWorker mixin 10.2.6.2 Script settings for workers 10.2.6.3 Dedicated workers and the Worker interface 10.2.6.4 Shared workers and the SharedWorker interface 10.2.7 Concurrent hardware capabilities 10.3 APIs available to workers 10.3.1 Importing scripts and libraries 10.3.2 The WorkerNavigator interface 10.3.3 The WorkerLocation interface 11 Worklets 11.1 Introduction 11.1.1 Motivations 11.1.2 Code idempotence 11.1.3 Speculative evaluation 11.2 Examples 11.2.1 Loading scripts 11.2.2 Registering a class and invoking its methods 11.3 Infrastructure 11.3.1 The global scope 11.3.1.1 Agents and event loops 11.3.1.2 Creation and termination 11.3.1.3 Script settings for worklets 11.3.2 The Worklet class 11.3.3 The worklet's lifetime 12 Web storage 12.1 Introduction 12.2 The API 12.2.1 The Storage interface 12.2.2 The sessionStorage getter 12.2.3 The localStorage getter 12.2.4 The StorageEvent interface 12.3 Privacy 12.3.1 User tracking 12.3.2 Sensitivity of data 12.4 Security 12.4.1 DNS spoofing attacks 12.4.2 Cross-directory attacks 12.4.3 Implementation risks 13 The HTML syntax 13.1 Writing HTML documents 13.1.1 The DOCTYPE 13.1.2 Elements 13.1.2.1 Start tags 13.1.2.2 End tags 13.1.2.3 Attributes 13.1.2.4 Optional tags 13.1.2.5 Restrictions on content models 13.1.2.6 Restrictions on the contents of raw text and escapable raw text elements 13.1.3 Text 13.1.3.1 Newlines 13.1.4 Character references 13.1.5 CDATA sections 13.1.6 Comments 13.2 Parsing HTML documents 13.2.1 Overview of the parsing model 13.2.2 Parse errors 13.2.3 The input byte stream 13.2.3.1 Parsing with a known character encoding 13.2.3.2 Determining the character encoding 13.2.3.3 Character encodings 13.2.3.4 Changing the encoding while parsing 13.2.3.5 Preprocessing the input stream 13.2.4 Parse state 13.2.4.1 The insertion mode 13.2.4.2 The stack of open elements 13.2.4.3 The list of active formatting elements 13.2.4.4 The element pointers 13.2.4.5 Other parsing state flags 13.2.5 Tokenization 13.2.5.1 Data state 13.2.5.2 RCDATA state 13.2.5.3 RAWTEXT state 13.2.5.4 Script data state 13.2.5.5 PLAINTEXT state 13.2.5.6 Tag open state 13.2.5.7 End tag open state 13.2.5.8 Tag name state 13.2.5.9 RCDATA less-than sign state 13.2.5.10 RCDATA end tag open state 13.2.5.11 RCDATA end tag name state 13.2.5.12 RAWTEXT less-than sign state 13.2.5.13 RAWTEXT end tag open state 13.2.5.14 RAWTEXT end tag name state 13.2.5.15 Script data less-than sign state 13.2.5.16 Script data end tag open state 13.2.5.17 Script data end tag name state 13.2.5.18 Script data escape start state 13.2.5.19 Script data escape start dash state 13.2.5.20 Script data escaped state 13.2.5.21 Script data escaped dash state 13.2.5.22 Script data escaped dash dash state 13.2.5.23 Script data escaped less-than sign state 13.2.5.24 Script data escaped end tag open state 13.2.5.25 Script data escaped end tag name state 13.2.5.26 Script data double escape start state 13.2.5.27 Script data double escaped state 13.2.5.28 Script data double escaped dash state 13.2.5.29 Script data double escaped dash dash state 13.2.5.30 Script data double escaped less-than sign state 13.2.5.31 Script data double escape end state 13.2.5.32 Before attribute name state 13.2.5.33 Attribute name state 13.2.5.34 After attribute name state 13.2.5.35 Before attribute value state 13.2.5.36 Attribute value (double-quoted) state 13.2.5.37 Attribute value (single-quoted) state 13.2.5.38 Attribute value (unquoted) state 13.2.5.39 After attribute value (quoted) state 13.2.5.40 Self-closing start tag state 13.2.5.41 Bogus comment state 13.2.5.42 Markup declaration open state 13.2.5.43 Comment start state 13.2.5.44 Comment start dash state 13.2.5.45 Comment state 13.2.5.46 Comment less-than sign state 13.2.5.47 Comment less-than sign bang state 13.2.5.48 Comment less-than sign bang dash state 13.2.5.49 Comment less-than sign bang dash dash state 13.2.5.50 Comment end dash state 13.2.5.51 Comment end state 13.2.5.52 Comment end bang state 13.2.5.53 DOCTYPE state 13.2.5.54 Before DOCTYPE name state 13.2.5.55 DOCTYPE name state 13.2.5.56 After DOCTYPE name state 13.2.5.57 After DOCTYPE public keyword state 13.2.5.58 Before DOCTYPE public identifier state 13.2.5.59 DOCTYPE public identifier (double-quoted) state 13.2.5.60 DOCTYPE public identifier (single-quoted) state 13.2.5.61 After DOCTYPE public identifier state 13.2.5.62 Between DOCTYPE public and system identifiers state 13.2.5.63 After DOCTYPE system keyword state 13.2.5.64 Before DOCTYPE system identifier state 13.2.5.65 DOCTYPE system identifier (double-quoted) state 13.2.5.66 DOCTYPE system identifier (single-quoted) state 13.2.5.67 After DOCTYPE system identifier state 13.2.5.68 Bogus DOCTYPE state 13.2.5.69 CDATA section state 13.2.5.70 CDATA section bracket state 13.2.5.71 CDATA section end state 13.2.5.72 Character reference state 13.2.5.73 Named character reference state 13.2.5.74 Ambiguous ampersand state 13.2.5.75 Numeric character reference state 13.2.5.76 Hexadecimal character reference start state 13.2.5.77 Decimal character reference start state 13.2.5.78 Hexadecimal character reference state 13.2.5.79 Decimal character reference state 13.2.5.80 Numeric character reference end state 13.2.6 Tree construction 13.2.6.1 Creating and inserting nodes 13.2.6.2 Parsing elements that contain only text 13.2.6.3 Closing elements that have implied end tags 13.2.6.4 The rules for parsing tokens in HTML content 13.2.6.4.1 The "initial" insertion mode 13.2.6.4.2 The "before html" insertion mode 13.2.6.4.3 The "before head" insertion mode 13.2.6.4.4 The "in head" insertion mode 13.2.6.4.5 The "in head noscript" insertion mode 13.2.6.4.6 The "after head" insertion mode 13.2.6.4.7 The "in body" insertion mode 13.2.6.4.8 The "text" insertion mode 13.2.6.4.9 The "in table" insertion mode 13.2.6.4.10 The "in table text" insertion mode 13.2.6.4.11 The "in caption" insertion mode 13.2.6.4.12 The "in column group" insertion mode 13.2.6.4.13 The "in table body" insertion mode 13.2.6.4.14 The "in row" insertion mode 13.2.6.4.15 The "in cell" insertion mode 13.2.6.4.16 The "in select" insertion mode 13.2.6.4.17 The "in select in table" insertion mode 13.2.6.4.18 The "in template" insertion mode 13.2.6.4.19 The "after body" insertion mode 13.2.6.4.20 The "in frameset" insertion mode 13.2.6.4.21 The "after frameset" insertion mode 13.2.6.4.22 The "after after body" insertion mode 13.2.6.4.23 The "after after frameset" insertion mode 13.2.6.5 The rules for parsing tokens in foreign content 13.2.7 The end 13.2.8 Speculative HTML parsing 13.2.9 Coercing an HTML DOM into an infoset 13.2.10 An introduction to error handling and strange cases in the parser 13.2.10.1 Misnested tags: 13.2.10.2 Misnested tags: 13.2.10.3 Unexpected markup in tables 13.2.10.4 Scripts that modify the page as it is being parsed 13.2.10.5 The execution of scripts that are moving across multiple documents 13.2.10.6 Unclosed formatting elements 13.3 Serializing HTML fragments 13.4 Parsing HTML fragments 13.5 Named character references 14 The XML syntax 14.1 Writing documents in the XML syntax 14.2 Parsing XML documents 14.3 Serializing XML fragments 14.4 Parsing XML fragments 15 Rendering 15.1 Introduction 15.2 The CSS user agent style sheet and presentational hints 15.3 Non-replaced elements 15.3.1 Hidden elements 15.3.2 The page 15.3.3 Flow content 15.3.4 Phrasing content 15.3.5 Bidirectional text 15.3.6 Sections and headings 15.3.7 Lists 15.3.8 Tables 15.3.9 Margin collapsing quirks 15.3.10 Form controls 15.3.11 The hr element 15.3.12 The fieldset and legend elements 15.4 Replaced elements 15.4.1 Embedded content 15.4.2 Images 15.4.3 Attributes for embedded content and images 15.4.4 Image maps 15.5 Widgets 15.5.1 Introduction 15.5.2 Button layout 15.5.3 The button element 15.5.4 The details and summary elements 15.5.5 The input element as a text entry widget 15.5.6 The input element as domain-specific widgets 15.5.7 The input element as a range control 15.5.8 The input element as a color well 15.5.9 The input element as a checkbox and radio button widgets 15.5.10 The input element as a file upload control 15.5.11 The input element as a button 15.5.12 The marquee element 15.5.13 The meter element 15.5.14 The progress element 15.5.15 The select element 15.5.16 The textarea element 15.6 Frames and framesets 15.7 Interactive media 15.7.1 Links, forms, and navigation 15.7.2 The title attribute 15.7.3 Editing hosts 15.7.4 Text rendered in native user interfaces 15.8 Print media 15.9 Unstyled XML documents 16 Obsolete features 16.1 Obsolete but conforming features 16.1.1 Warnings for obsolete but conforming features 16.2 Non-conforming features 16.3 Requirements for implementations 16.3.1 The marquee element 16.3.2 Frames 16.3.3 Other elements, attributes and APIs 17 IANA considerations 17.1 text/html 17.2 multipart/x-mixed-replace 17.3 application/xhtml+xml 17.4 text/ping 17.5 application/microdata+json 17.6 text/event-stream 17.7 ` Cross-Origin-Embedder-Policy` 17.8 ` Cross-Origin-Embedder-Policy-Report-Only` 17.9 ` Cross-Origin-Opener-Policy` 17.10 ` Cross-Origin-Opener-Policy-Report-Only` 17.11 ` Origin-Agent-Cluster` 17.12 ` Ping-From` 17.13 ` Ping-To` 17.14 ` Refresh` 17.15 ` Last-Event-ID` 17.16 ` X-Frame-Options` 17.17 web+ scheme prefix Index Elements Element content categories Attributes Element Interfaces All Interfaces Events MIME Types References Acknowledgments Intellectual property rights
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Git Repo List My Repos: https://github.com/bgoonz/03-fetch-data https://github.com/bgoonz/a-whole-bunch-o-gatsby-templates https://github.com/bgoonz/activity-box https://github.com/bgoonz/All-Undergrad-Archive https://github.com/bgoonz/alternate-blog-theme https://github.com/bgoonz/anki-cards https://github.com/bgoonz/ask-me-anything https://github.com/bgoonz/atlassian-templates https://github.com/bgoonz/Authentication-Notes https://github.com/bgoonz/bash-commands-walkthrough https://github.com/bgoonz/bash-config-backup https://github.com/bgoonz/bash-shell-utility-functions https://github.com/bgoonz/bass-station https://github.com/bgoonz/bgoonz https://github.com/bgoonz/BGOONZBLOG2.0STABLE https://github.com/bgoonz/BGOONZ BLOG 2.0 https://github.com/bgoonz/Binary-Search https://github.com/bgoonz/blog-2.o-versions https://github.com/bgoonz/blog-templates https://github.com/bgoonz/blog-w-comments https://github.com/bgoonz/Blog2.0-August-Super-Stable https://github.com/bgoonz/bootstrap-sidebar-template https://github.com/bgoonz/callbacks https://github.com/bgoonz/Comments https://github.com/bgoonz/commercejs-nextjs-demo-store https://github.com/bgoonz/Common-npm-Readme-Compilation https://github.com/bgoonz/Comparing-Web-Development-Bootcamps-2021 https://github.com/bgoonz/Connect-Four-Final-Version https://github.com/bgoonz/convert-folder-contents-2-website https://github.com/bgoonz/Copy-2-Clipboard-jQuery https://github.com/bgoonz/Data-Structures-Algos-Codebase https://github.com/bgoonz/DATA STRUC PYTHON_NOTES https://github.com/bgoonz/design-home-page-with-routes-bq5v7k https://github.com/bgoonz/docs-collection https://github.com/bgoonz/Documentation-site-react https://github.com/bgoonz/DS-ALGO-OFFICIAL https://github.com/bgoonz/DS-AND-ALGO-Notes-P2 https://github.com/bgoonz/ecommerce-interactive https://github.com/bgoonz/embedable-repl-and-integrated-code-space-playground https://github.com/bgoonz/excel2html-table https://github.com/bgoonz/Exploring-Promises https://github.com/bgoonz/express-API-template https://github.com/bgoonz/Express-basic-server-template https://github.com/bgoonz/express-knex-postgres-boilerplate https://github.com/bgoonz/EXPRESS-NOTES https://github.com/bgoonz/fast-fourier-transform- https://github.com/bgoonz/form-builder-vanilla-js https://github.com/bgoonz/Front-End-Frameworks-Practice https://github.com/bgoonz/full-stack-react-redux https://github.com/bgoonz/Full-Text-Search https://github.com/bgoonz/Games https://github.com/bgoonz/gatsby-netlify-cms-norwex https://github.com/bgoonz/gatsby-react-portfolio https://github.com/bgoonz/GIT-CDN-FILES https://github.com/bgoonz/GIT-HTML-PREVIEW-TOOL https://github.com/bgoonz/gitbook https://github.com/bgoonz/github-readme-stats https://github.com/bgoonz/github-reference-repo https://github.com/bgoonz/GoalsTracker https://github.com/bgoonz/graphql-experimentation https://github.com/bgoonz/https __mihirbeg.com https://github.com/bgoonz/iframe-showcase https://github.com/bgoonz/Image-Archive-Traning-Data https://github.com/bgoonz/Independent-Blog-Entries https://github.com/bgoonz/INTERVIEW-PREP-COMPLETE https://github.com/bgoonz/JAMSTACK-TEMPLATES https://github.com/bgoonz/Javascript-Best-Practices_--Tools https://github.com/bgoonz/jsanimate https://github.com/bgoonz/Jupyter-Notebooks https://github.com/bgoonz/Lambda https://github.com/bgoonz/Lambda-Resource-Static-Assets https://github.com/bgoonz/learning-nextjs https://github.com/bgoonz/Learning-Redux https://github.com/bgoonz/Links-Shortcut-Site https://github.com/bgoonz/live-examples https://github.com/bgoonz/live-form https://github.com/bgoonz/loadash-es6-refactor https://github.com/bgoonz/markdown-css https://github.com/bgoonz/Markdown-Templates https://github.com/bgoonz/meditation-app https://github.com/bgoonz/MihirBegMusicLab https://github.com/bgoonz/MihirBegMusicV3 https://github.com/bgoonz/Mihir Beg Final https://github.com/bgoonz/mini-project-showcase https://github.com/bgoonz/Music-Theory-n-Web-Synth-Keyboard https://github.com/bgoonz/my-gists https://github.com/bgoonz/My-Medium-Blog https://github.com/bgoonz/nextjs-netlify-blog-template https://github.com/bgoonz/norwex-coff-ecom https://github.com/bgoonz/old-c-and-cpp-repos-from-undergrad https://github.com/bgoonz/old-code-from-undergrad https://github.com/bgoonz/picture-man-bob-v2 https://github.com/bgoonz/Project-Showcase https://github.com/bgoonz/promises-with-async-and-await https://github.com/bgoonz/psql-practice https://github.com/bgoonz/python-playground-embed https://github.com/bgoonz/python-practice-notes https://github.com/bgoonz/python-scripts https://github.com/bgoonz/PYTHON_PRAC https://github.com/bgoonz/random-list-of-embedable-content https://hub.com/bgoonz/random-static-html-page-deploy https://hub.com/bgoonz/React-movie-app https://hub.com/bgoonz/react-redux-medium-clone https://hub.com/bgoonz/react-redux-notes-v5 https://hub.com/bgoonz/react-redux-registration-login-example https://hub.com/bgoonz/React Notes V3 https://hub.com/bgoonz/Recursion-Practice-Website https://hub.com/bgoonz/Regex-and-Express-JS https://hub.com/bgoonz/repo-utils https://hub.com/bgoonz/resume-cv-portfolio-samples https://hub.com/bgoonz/Revamped-Automatic-Guitar-Effect-Triggering https://hub.com/bgoonz/scope-closure-context https://hub.com/bgoonz/Shell-Script-Practice https://hub.com/bgoonz/site-analysis https://hub.com/bgoonz/sorting-algorithms https://hub.com/bgoonz/sorting-algos https://hub.com/bgoonz/sqlite3-nodejs-demo https://hub.com/bgoonz/stalk-photos-web-assets https://hub.com/bgoonz/Standalone-Metranome https://hub.com/bgoonz/Star-wars-API-Promise-take2 https://hub.com/bgoonz/Static-Study-Site https://hub.com/bgoonz/styling-templates https://hub.com/bgoonz/supertemp https://hub.com/bgoonz/Ternary-converter https://hub.com/bgoonz/TetrisJS https://hub.com/bgoonz/TexTools https://hub.com/bgoonz/The-Algorithms https://hub.com/bgoonz/TRASH https://hub.com/bgoonz/Triggered-Guitar-Effects-Platform https://hub.com/bgoonz/Useful-Snippets-js https://hub.com/bgoonz/UsefulResourceRepo2.0 https://hub.com/bgoonz/vscode-customized-config https://hub.com/bgoonz/vscode-Extension-readmes https://hub.com/bgoonz/web-crawler-node https://hub.com/bgoonz/web-dev-interview-prep-quiz-website https://hub.com/bgoonz/web-dev-notes-resource-site https://hub.com/bgoonz/web-dev-setup-checker https://hub.com/bgoonz/WEB-DEV-TOOLS-HUB https://hub.com/bgoonz/web-dev-utils-package https://hub.com/bgoonz/WebAudioDaw https://hub.com/bgoonz/website
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Git Reference Git Reference Git is a distributed version control and source code management system. It does this through a series of snapshots of your project, and it works with those snapshots to provide you with functionality to version and manage your source code. Versioning Concepts What is version control? Version control is a system that records changes to a file(s), over time. Centralized Versioning vs. Distributed Versioning Centralized version control focuses on synchronizing, tracking, and backing up files. Distributed version control focuses on sharing changes. Every change has a unique id. Distributed systems have no defined structure. You could easily have a SVN style, centralized system, with git. Additional Information Why Use Git? Can work offline. Collaborating with others is easy! Branching is easy! Branching is fast! Merging is easy! Git is fast. Git is flexible. Git Architecture Repository A set of files, directories, historical records, commits, and heads. Imagine it as a source code data structure, with the attribute that each source code "element" gives you access to its revision history, among other things. A git repository is comprised of the .git directory & working tree..git Directory (component of repository) The .git directory contains all the configurations, logs, branches, HEAD, and more. Detailed List. Working Tree (component of repository) This is basically the directories and files in your repository. It is often referred to as your working directory. Index (component of .git dir) The Index is the staging area in git. It's basically a layer that separates your working tree from the Git repository. This gives developers more power over what gets sent to the Git repository. Commit A git commit is a snapshot of a set of changes, or manipulations to your Working Tree. For example, if you added 5 files, and removed 2 others, these changes will be contained in a commit (or snapshot). This commit can then be pushed to other repositories, or not! Branch A branch is essentially a pointer to the last commit you made. As you go on committing, this pointer will automatically update to point to the latest commit. Tag A tag is a mark on specific point in history. Typically people use this functionality to mark release points (v1.0, and so on). HEAD and head (component of .git dir) HEAD is a pointer that points to the current branch. A repository only has 1 active HEAD. head is a pointer that points to any commit. A repository can have any number of heads. Stages of Git Modified - Changes have been made to a file but file has not been committed to Git Database yet Staged - Marks a modified file to go into your next commit snapshot Committed - Files have been committed to the Git Database Conceptual Resources Git For Computer Scientists Git For Designers Commands init Create an empty Git repository. The Git repository's settings, stored information, and more is stored in a directory (a folder) named ".git".$ git init config To configure settings. Whether it be for the repository, the system itself, or global configurations ( global config file is ~/.gitconfig ).# Print & Set Some Basic Config Variables (Global) $ git config --global user.email "MyEmail@Zoho.com" $ git config --global user.name "My Name" Learn More About git config. help To give you quick access to an extremely detailed guide of each command. Or to just give you a quick reminder of some semantics.# Quickly check available commands $ git help # Check all available commands $ git help -a # Command specific help - user manual # git help <command_here> $ git help add $ git help commit $ git help init # or git <command_here> --help $ git add --help $ git commit --help $ git init --help ignore files To intentionally untrack file(s) & folder(s) from git. Typically meant for private & temp files which would otherwise be shared in the repository.$ echo "temp/" >> .gitignore $ echo "private_key" >> .gitignore status To show differences between the index file (basically your working copy/repo) and the current HEAD commit.# Will display the branch, untracked files, changes and other differences $ git status # To learn other "tid bits" about git status $ git help status add To add files to the staging area/index. If you do not git add new files to the staging area/index, they will not be included in commits!# add a file in your current working directory $ git add HelloWorld.java # add a file in a nested dir $ git add /path/to/file/HelloWorld.c # Regular Expression support! $ git add ./*.java # You can also add everything in your working directory to the staging area. $ git add -A This only adds a file to the staging area/index, it doesn't commit it to the working directory/repo. branch Manage your branches. You can view, edit, create, delete branches using this command.# list existing branches & remotes $ git branch -a # create a new branch $ git branch myNewBranch # delete a branch $ git branch -d myBranch # rename a branch # git branch -m <oldname> <newname> $ git branch -m myBranchName myNewBranchName # edit a branch's description $ git branch myBranchName --edit-description tag Manage your tags# List tags $ git tag # Create a annotated tag # The -m specifies a tagging message, which is stored with the tag. # If you don't specify a message for an annotated tag, # Git launches your editor so you can type it in. $ git tag -a v2.0 -m 'my version 2.0' # Show info about tag # That shows the tagger information, the date the commit was tagged, # and the annotation message before showing the commit information. $ git show v2.0 # Push a single tag to remote $ git push origin v2.0 # Push a lot of tags to remote $ git push origin --tags checkout Updates all files in the working tree to match the version in the index, or specified tree.# Checkout a repo - defaults to master branch $ git checkout # Checkout a specified branch $ git checkout branchName # Create a new branch & switch to it # equivalent to "git branch <name>; git checkout <name>" $ git checkout -b newBranch clone Clones, or copies, an existing repository into a new directory. It also adds remote-tracking branches for each branch in the cloned repo, which allows you to push to a remote branch.# Clone learnxinyminutes-docs $ git clone https://github.com/adambard/learnxinyminutes-docs.git # shallow clone - faster cloning that pulls only latest snapshot $ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git # clone only a specific branch $ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch commit Stores the current contents of the index in a new "commit." This commit contains the changes made and a message created by the user.# commit with a message $ git commit -m "Added multiplyNumbers() function to HelloWorld.c" # signed commit with a message (user.signingkey must have been set # with your GPG key e.g. git config --global user.signingkey 5173AAD5) $ git commit -S -m "signed commit message" # automatically stage modified or deleted files, except new files, and then commit $ git commit -a -m "Modified foo.php and removed bar.php" # change last commit (this deletes previous commit with a fresh commit) $ git commit --amend -m "Correct message" diff Shows differences between a file in the working directory, index and commits.# Show difference between your working dir and the index $ git diff # Show differences between the index and the most recent commit. $ git diff --cached # Show differences between your working dir and the most recent commit $ git diff HEAD grep Allows you to quickly search a repository. Optional Configurations:# Thanks to Travis Jeffery for these # Set line numbers to be shown in grep search results $ git config --global grep.lineNumber true # Make search results more readable, including grouping $ git config --global alias.g "grep --break --heading --line-number" # Search for "variableName" in all java files $ git grep 'variableName' -- '*.java' # Search for a line that contains "arrayListName" and, "add" or "remove" $ git grep -e 'arrayListName' --and \( -e add -e remove \) Google is your friend; for more examples Git Grep Ninja log Display commits to the repository.# Show all commits $ git log # Show only commit message & ref $ git log --oneline # Show merge commits only $ git log --merges # Show all commits represented by an ASCII graph $ git log --graph merge"Merge" in changes from external commits into the current branch.# Merge the specified branch into the current. $ git merge branchName # Always generate a merge commit when merging $ git merge --no-ff branchName mv Rename or move a file# Renaming a file $ git mv HelloWorld.c HelloNewWorld.c # Moving a file $ git mv HelloWorld.c ./new/path/HelloWorld.c # Force rename or move # "existingFile" already exists in the directory, will be overwritten $ git mv -f myFile existingFile pull Pulls from a repository and merges it with another branch.# Update your local repo, by merging in new changes # from the remote "origin" and "master" branch. # git pull <remote> <branch> $ git pull origin master # By default, git pull will update your current branch # by merging in new changes from its remote-tracking branch $ git pull # Merge in changes from remote branch and rebase # branch commits onto your local repo, like: "git fetch <remote> <branch>, git # rebase <remote>/<branch>" $ git pull origin master --rebase push Push and merge changes from a branch to a remote & branch.# Push and merge changes from a local repo to a # remote named "origin" and "master" branch. # git push <remote> <branch> $ git push origin master # By default, git push will push and merge changes from # the current branch to its remote-tracking branch $ git push # To link up current local branch with a remote branch, add -u flag: $ git push -u origin master # Now, anytime you want to push from that same local branch, use shortcut: $ git push stash Stashing takes the dirty state of your working directory and saves it on a stack of unfinished changes that you can reapply at any time. Let's say you've been doing some work in your git repo, but you want to pull from the remote. Since you have dirty (uncommitted) changes to some files, you are not able to run git pull. Instead, you can run git stash to save your changes onto a stack!$ git stash Saved working directory and index state \ "WIP on master: 049d078 added the index file" HEAD is now at 049d078 added the index file (To restore them type "git stash apply") Now you can pull! git pull ...changes apply... Now check that everything is OK$ git status # On branch master nothing to commit, working directory clean You can see what "hunks" you've stashed so far using git stash list. Since the "hunks" are stored in a Last-In-First-Out stack, our most recent change will be at top.$ git stash list stash@{0}: WIP on master: 049d078 added the index file stash@{1}: WIP on master: c264051 Revert "added file_size" stash@{2}: WIP on master: 21d80a5 added number to log Now let's apply our dirty changes back by popping them off the stack.$ git stash pop # On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # # modified: index.html # modified: lib/simplegit.rb # git stash apply does the same thing Now you're ready to get back to work on your stuff! Additional Reading. rebase (caution) Take all changes that were committed on one branch, and replay them onto another branch. Do not rebase commits that you have pushed to a public repo.# Rebase experimentBranch onto master # git rebase <basebranch> <topicbranch> $ git rebase master experimentBranch Additional Reading. reset (caution) Reset the current HEAD to the specified state. This allows you to undo merges, pulls, commits, adds, and more. It's a great command but also dangerous if you don't know what you are doing.# Reset the staging area, to match the latest commit (leaves dir unchanged) $ git reset # Reset the staging area, to match the latest commit, and overwrite working dir $ git reset --hard # Moves the current branch tip to the specified commit (leaves dir unchanged) # all changes still exist in the directory. $ git reset 31f2bb1 # Moves the current branch tip backward to the specified commit # and makes the working dir match (deletes uncommitted changes and all commits # after the specified commit). $ git reset --hard 31f2bb1 reflog (caution) Reflog will list most of the git commands you have done for a given time period, default 90 days. This give you the chance to reverse any git commands that have gone wrong (for instance, if a rebase has broken your application). You can do this: git reflog to list all of the git commands for the rebase 38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog 38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators 4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown 34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666) ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748) 2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d Select where to reset to, in our case its 2e6c386, or HEAD@{5}'git reset --hard HEAD@{5}' this will reset your repo to that head You can start the rebase again or leave it alone. Additional Reading. revert Revert can be used to undo a commit. It should not be confused with reset which restores the state of a project to a previous point. Revert will add a new commit which is the inverse of the specified commit, thus reverting it.# Revert a specified commit $ git revert <commit> rm The opposite of git add, git rm removes files from the current working tree.# remove HelloWorld.c $ git rm HelloWorld.c # Remove a file from a nested dir $ git rm /pather/to/the/file/HelloWorld.c git checkout git reset git restore git switch I'll throw in one more, the misnamed git revert, as well. From an end-user perspective All you need are git checkout, git reset, and git revert. These commands have been in Git all along. But git checkout has, in effect, two modes of operation. One mode is "safe": it won't accidentally destroy any unsaved work. The other mode is "unsafe": if you use it, and it tells Git to wipe out some unsaved file, Git assumes that (a) you knew it meant that and (b) you really did mean to wipe out your unsaved file, so Git immediately wipes out your unsaved file. This is not very friendly, so the Git folks finally---after years of users griping---split git checkout into two new commands. This leads us to: From a historical perspective git restore is new, having first come into existence in August 2019, in Git 2.23. git reset is very old, having been in Git all along, dating back to before 2005. Both commands have the ability to destroy unsaved work. The git switch command is also new, introduced along with git restore in Git 2.23. It implements the "safe half" of git checkout; git restore implements the "unsafe half". When would you use which command? This is the most complicated part, and to really understand it, we need to know the following items: Git is really all about commits. Commits get stored in the Git repository. The git push and git fetch commands transfer commits---whole commits, as an all-or-nothing deal^1^---to the other Git. You either have all of a commit, or you don't have it. Other commands, such as git merge or git rebase, all work with local commits. The pull command runs fetch (to get commits) followed by a second command to work with the commits once they're local. New commits add to the repository. You almost never remove a commit from the repository. Only one of the five commands listed here---checkout, reset, restore, revert, and switch---is capable of removing commits.^2^ Each commit is numbered by its hash ID, which is unique to that one particular commit. It's actually computed from what's in the commit, which is how Git makes these numbers work across all Gits eveywhere. This means that what is in the commit is frozen for all time: if you change anything, what you get is a new commit with a new number, and the old commit is still there, with its same old number. Each commit stores two things: a snapshot, and metadata. The metadata include the hash ID(s) of some previous commit(s). This makes commits form backwards-looking chains. A branch name holds the hash ID of one commit. This makes the branch name find that commit, which in turn means two things: that particular commit is the tip commit of that branch; and all commits leading up to and including that tip commit are on that branch. We're also going to talk about Git's index in a moment, and your working tree. They're separate from these but worth mentioning early, especially since the index has three names: Git sometimes calls it the index, sometimes calls it the staging area, and sometimes---rarely these days---calls it the cache. All three names refer to the same thing. Everything up through the branch name is, I think, best understood via pictures (at least for most people). If we draw a series of commits, with newer commits towards the right, using o for each commit and omitting some commits for space or whatever, we get something like this: o--o---o <-- feature-top /\ o--o--o--o--...--o---o--o <-- main \ / o--o--...--o--o <-- feature-hull which, as you can see, is a boat repository. 😀 There are three branches. The mainline branch holds every commit, including all the commits on the top row and bottom (hull) row. The feature-top branch holds the top three commits and also the three commits along the main line to the left, but not any of the commits on the bottom row. All the connectors between commits are---well, should be but I don't have a good enough font---one-way arrows, pointing left, or down-and-left, or up-and-left. These "arrows", or one way connections from commit to commit, are technically arcs, or one-way edges, in a directed graph. This directed graph is one without cycles, making it a Directed Acyclic Graph or DAG, which has a bunch of properties that are useful to Git. If you're just using Git to store files inside commits, all you really care about are the round o nodes or vertices (again two words for the same thing), each of which acts to store your files, but you should at least be vaguely aware of how they are arranged. It matters, especially because of merges. Merge commits are those with two outgoing arcs, pointing backwards to two of what Git calls parent commits. The child commit is the one "later": just as human parents are always older than their children, Git parent commits are older than their children. We need one more thing, though: Where do new commits come from? We noted that what's in a commit---both the snapshot, holding all the files, and the metadata, holding the rest of the information Git keeps about a commit---is all read-only. Your files are not only frozen, they're also transformed, and the transformed data are then de-duplicated, so that even though every commit has a full snapshot of every file, the repository itself stays relatively slim. But this means that the files in a commit can only be read by Git, and nothing---not even Git itself---can write to them. They get saved once, and are de-duplicated from then on. The commits act as archives, almost like tar or rar or winzip or whatever. To work with a Git repository, then, we have to have Git extract the files. This takes the files out of some commit, turning those special archive-formatted things into regular, usable files. Note that Git may well be able to store files that your computer literally can't store: a classic example is a file named aux.h, for some C program, on a Windows machine. We won't go into all the details, but it is theoretically possible to still get work done with this repository, which was probably built on a Linux system, even if you're on a Windows system where you can't work with the aux.h file directly. Anyway, assuming there are no nasty little surprises like aux.h, you would just run git checkout or git switch to get some commit out of Git. This will fill in your working tree, populating it from the files stored in the tip commit of some branch. The tip commit is, again, the last commit on that branch, as found by the branch name. Your git checkout or git switch selected that commit to be the current commit, by selecting that branch name to be the current branch. You now have all the files from that commit, in an area where you can see them and work on them: your working tree. Note that the files in your working tree are not actually in Git itself. They were just extracted from Git. This matters a lot, because when git checkout extracts the files from Git, it actually puts each file in two places. One of those places is the ordinary everyday file you see and work on / with. The other place Git puts each file is into Git's index. As I mentioned a moment ago, the index has three names: index, staging area, and cache. All refer to the same thing: the place Git sticks these "copies" of each file. Each one is actually pre-de-duplicated, so the word "copy" is slightly wrong, but---unlike much of the rest of its innards---Git actually does a really good job of hiding the de-duplication aspect. Unless you start getting into internal commands like git ls-files and git update-index, you don't need to know about this part, and can just think of the index as holding a copy of the file, ready to go into the next commit. What this all means for you as someone just using Git is that the index / staging-area acts as your proposed next commit. When you run git commit, Git is going to package up these copies of the file as the ones to be archived in the snapshot. The copies you have in your working tree are yours; the index / staging-area copies are Git's, ready to go. So, if you change your copies and want the changed copy to be what goes in the next snapshot, you must tell Git: Update the Git copy, in the Git index / staging-area. You do this with git add.^3^ The git add command means make the proposed-next-commit copy match the working-tree copy. It's the add command that does the updating: this is when Git compresses and de-duplicates the file and makes it ready for archiving, not at git commit time.^4^ Then, assuming you have some series of commits ending with the one with hash-N:[hash1] <-[hash2] ... <-[hashN] <--branch you run git commit, give it any metadata it needs (a commit log message), and you get an N+1'th commit:[hash1] <-[hash2] ... <-[hashN] <-[hashN+1] <--branch Git automatically updates the branch name to point to the new commit, which has therefore been added to the branch. Let's look at each of the various commands now: git checkout: this is a large and complicated command. We already saw this one, or at least, half of this one. We used it to pick out a branch name, and therefore a particular commit. This kind of checkout first looks at our current commit, index, and working tree. It makes sure that we have committed all our modified files, or---this part gets a bit complicated---that if we haven't committed all our modified files, switching to that other branch is "safe". If it's not safe, git checkout tells you that you can't switch due to having modified files. If it is safe, git checkout will switch; if you didn't mean to switch, you can just switch back. (See also Checkout another branch when there are uncommitted changes on the current branch) But git checkout has an unsafe half. Suppose you have modified some file in your working tree, such as README.md or aux.h or whatever. You now look back at what you changed and think: No, that's a bad idea. I should get rid of this change. I'd like the file back exactly as it was before. To get this---to wipe out your changes to, say, README.md---you can run: git checkout -- README.md The -- part here is optional. It's a good idea to use it, because it tells Git that the part that comes after -- is a file name, not a branch name. Suppose you have a branch named hello and a file named hello. What does: git checkout hello mean? Are we asking Git to clobber the file hello to remove the changes we made, or are we asking Git to check out the branch hello? To make this unambiguous, you have to write either: git checkout -- hello (clobber the file) or: git checkout hello -- (get the branch) This case, where there are branches and files or directories with the same name, is a particularly insidious one. It has bitten real users. It's why git switch exists now. The git switch command never means clobber my files. It only means do the safe kind of git checkout.(The git checkout command has been smartened up too, so that if you have the new commands and you run the "bad" kind of ambiguous git checkout, Git will just complain at you and do nothing at all. Either use the smarter split-up commands, or add the -- at the right place to pick which kind of operation you want.) More precisely, this kind of git checkout, ideally spelled git checkout -- *paths*, is a request for Git to copy files from Git's index to your working tree. This means clobber my files. You can also run git checkout *tree-ish* -- *paths*, where you add a commit hash ID^5^ to the command. This tells Git to copy the files from that commit, first to Git's index, and then on to your working tree. This, too, means clobber my files: the difference is where Git gets the copies of the files it's extracting. If you ran git add on some file and thus copied it into Git's index, you need git checkout HEAD -- *file* to get it back from the current commit. The copy that's in Git's index is the one you git add-ed. So these two forms of git checkout, with a commit hash ID (or the name HEAD), the optional --, and the file name, are the unsafe clobber my files forms. git reset: this is also a large and complicated command. There are, depending on how you count, up to about five or six different forms of git reset. We'll concentrate on a smaller subset here. git reset [ --hard | --mixed | --soft ] [ *commit* ] Here, we're asking Git to do several things. First, if we give a commit argument, such as HEAD or HEAD~3 or some such, we've picked a particular commit that Git should reset to. This is the kind of command that will remove commits by ejecting them off the end of the branch. Of all the commands listed here, this is the only one that removes any commits. One other command--- git commit --amend---has the effect of ejecting the last commit while putting on a new replacement, but that one is limited to ejecting one commit. Let's show this as a drawing. Suppose we have:...--E--F--G--H <-- branch That is, this branch, named branch, ends with four commits whose hash IDs we'll call E, F, G, and H in that order. The name branch currently stores the hash ID of the last of these commits, H. If we use git reset --hard HEAD~3, we're telling Git to eject the last three commits. The result is: F--G--H ??? / ...--E <-- branch The name branch now selects commit E, not commit H. If we did not write down (on paper, on a whiteboard, in a file) the hash IDs of the last three commits, they've just become somewhat hard to find. Git does gives a way to find them again, for a while, but mostly they just seem to be gone. The HEAD~3 part of this command is how we chose to drop the last three commits. It's part of a whole sub-topic in Git, documented in the gitrevisions manual, on ways to name specific commits. The reset command just needs the hash ID of an actual commit, or anything equivalent, and HEAD~3 means go back three first-parent steps, which in this case gets us from commit H back to commit E. The --hard part of the git reset is how we tell Git what to do with (a) its index and (b) our working tree files. We have three choices here:--soft tells Git: leave both alone. Git will move the branch name without touching the index or our working tree. If you run git commit now, whatever is (still) in the index is what goes into the new commit. If the index matches the snapshot in commit H, this gets you a new commit whose snapshot is H, but whose parent is E, as if commits F through H had all been collapsed into a single new commit. People usually call this squashing.--mixed tells Git: reset your index, but leave my working tree alone. Git will move the branch name, then replace every file that is in the index with the one from the newly selected commit. But Git will leave all your working tree files alone. This means that as far as Git is concerned, you can start git add ing files to make a new commit. Your new commit won't match H unless you git add everything, so this means you could, for instance, build a new intermediate commit, sort of like E+F or something, if you wanted.--hard tells Git: *reset your index and my working tree.* Git will move the branch name, replace all the files in its index, and replace all the files in your working tree, all as one big thing. It's now as if you never made those three commits at all. You no longer have the files from F, or G, or H: you have the files from commit E. Note that if you leave out the commit part of this kind of (hard/soft/mixed) reset, Git will use HEAD. Since HEAD names the current commit (as selected by the current branch name), this leaves the branch name itself unchanged: it still selects the same commit as before. So this is only useful with --mixed or --hard, because git reset --soft, with no commit hash ID, means don't move the branch name, don't change Git's index, and don't touch my working tree. Those are the three things this kind of git reset can do---move the branch name, change what's in Git's index, and change what's in your working tree---and you just ruled all three out. Git is OK with doing nothing, but why bother? git reset [ *tree-ish* ] -- *path* This is the other kind of git reset we'll care about here. It's a bit like a mixed reset, in that it means clobber some of the index copies of files, but here you specify which files to clobber. It's also a bit unlike a mixed reset, because this kind of git reset will never move the branch name. Instead, you pick which files you want copied from somewhere. The somewhere is the tree-ish you give; if you don't give one, the somewhere is HEAD, i.e., the current commit. This can only restore files in the proposed next commit to the form they have in some existing commit. By defaulting to the current existing commit, this kind of git reset -- *path* has the effect of undoing a git add -- *path*.^6^ There are several other forms of git reset. To see what they all mean, consult the documentation. git restore: this got split off from git checkout. Basically, this does the same thing as the various forms of git checkout and git reset that clobber files (in your working tree and/or in Git's index). It's smarter than the old git checkout-and-clobber-my-work variant, in that you get to choose where the files come from and where they go, all in the one command line. To do what you used to do with git checkout -- *file*, you just run git restore --staged --worktree -- *file*. (You can leave out the -- part, as with git checkout, in most cases, but it's just generally wise to get in the habit of using it. Like git add, this command is designed such that only files named -whatever are actually problematic.) To do what you used to do with git reset -- *file*, you just run git restore --staged -- *file*. That is, you tell git restore to copy from HEAD to staging area / index, which is how git reset operates. Note that you can copy a file from some existing commit, to Git's index, without touching your working tree copy of that file: git restore --source *commit* --staged -- *file* does that. You can't do that at all with the old git checkout but you can do that with the old git reset, as git reset *commit* -- *file*. And, you can copy a file from some existing commit, to your working tree, without touching the staged copy: git restore --source *commit* --worktree -- *file* does that. The overlapping part (restore and reset) exists because git restore is new, and this kind of restore makes sense; probably, ideally, we should always use git restore here, instead of using the old git reset way of doing things, but Git tries to maintain backwards compatibility. The new ability---to copy from any arbitrary source, to your working tree, without touching Git's index / staging-area copy---is just that: new. You couldn't do it before. (You could run git show *commit*:*path* > *path*, before, but that falls outside our five commands to examine.) git switch: this just does the "safe half" of git checkout. That's really all you need to know. Using git switch, without --force, Git won't overwrite your unsaved work, even if you make a typo or whatever. The old git checkout command could overwrite unsaved work: if your typo turns a branch name into a file name, for instance, well, oops. git revert (I added this for completeness): this makes a new commit. The point of the new commit is to back out what someone did in some existing commit. You therefore need to name the existing commit that revert should back out. This command probably should have been named git backout. If you back out the most recent commit, this does revert to the second-most-recent snapshot: ...--G--H <-- branch becomes: ...--G--H--Ħ <-- branch where commit Ħ (H-bar) "undoes" commit H and therefore leaves us with the same files as commit G. But we don't have to undo the most recent commit. We could take: ...--E--F--G--H <-- branch and add a commit Ǝ that undoes E to get: ...--E--F--G--H--Ǝ <-- branch which may not match the source snapshot of any previous commit! Further Information tryGit - A fun interactive way to learn Git. Learn Git Branching - the most visual and interactive way to learn Git on the web Udemy Git Tutorial: A Comprehensive Guide Git Immersion - A Guided tour that walks through the fundamentals of git git-scm - Video Tutorials git-scm - Documentation Atlassian Git - Tutorials & Workflows SalesForce Cheat Sheet GitGuys Git - the simple guide Pro Git An introduction to Git and GitHub for Beginners (Tutorial) The New Boston tutorial to Git covering basic commands and workflow
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    ECMAScript 6 Introduction ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. ES6 is a significant update to the language, and the first update to the language since ES5 was standardized in 2009. Implementation of these features in major JavaScript engines is underway now. See the ES6 standard for full specification of the ECMAScript 6 language. ES6 includes the following new features: arrows classes enhanced object literals template strings destructuring default + rest + spread let + const iterators + for..of generators unicode modules module loaders map + set + weakmap + weakset proxies symbols subclassable built-ins promises math + number + string + array + object APIs binary and octal literals reflect api tail calls ECMAScript 6 Features Arrows Arrows are a function shorthand using the => syntax. They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both statement block bodies as well as expression bodies which return the value of the expression. Unlike functions, arrows share the same lexical this as their surrounding code.// Expression bodies var odds = evens.map(v => v + 1); var nums = evens.map((v, i) => v + i); var pairs = evens.map(v => ({even: v, odd: v + 1})); // Statement bodies nums.forEach(v => { if (v % 5 === 0) fives.push(v); }); // Lexical this var bob = { _name: "Bob", _friends: [], printFriends() { this._friends.forEach(f => console.log(this._name + " knows " + f)); } } More info: MDN Arrow Functions Classes ES6 classes are a simple sugar over the prototype-based OO pattern. Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors. class SkinnedMesh extends THREE.Mesh { constructor(geometry, materials) { super(geometry, materials); this.idMatrix = SkinnedMesh.defaultMatrix(); this.bones = []; this.boneMatrices = []; //... } update(camera) { //... super.update(); } get boneCount() { return this.bones.length; } set matrixType(matrixType) { this.idMatrix = SkinnedMesh[matrixType](); } static defaultMatrix() { return new THREE.Matrix4(); } } More info: MDN Classes Enhanced Object Literals Object literals are extended to support setting the prototype at construction, shorthand for foo: foo assignments, defining methods, making super calls, and computing property names with expressions. Together, these also bring object literals and class declarations closer together, and let object-based design benefit from some of the same conveniences. var obj = { // __proto__ __proto__: theProtoObj, // Shorthand for 'handler: handler' handler, // Methods toString() { // Super calls return "d " + super.toString(); }, // Computed (dynamic) property names [ 'prop_' + (() => 42)() ]: 42 }; More info: MDN Grammar and types: Object literals Template Strings Template strings provide syntactic sugar for constructing strings. This is similar to string interpolation features in Perl, Python and more. Optionally, a tag can be added to allow the string construction to be customized, avoiding injection attacks or constructing higher level data structures from string contents.// Basic literal string creation `In JavaScript '\n' is a line-feed.` // Multiline strings `In JavaScript this is not legal.` // String interpolation var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?` // Construct an HTTP request prefix is used to interpret the replacements and construction POST`http://foo.org/bar?a=${a}&b=${b} Content-Type: application/json X-Credentials: ${credentials} { "foo": ${foo}, "bar": ${bar}}`(myOnReadyStateChangeHandler); More info: MDN Template Strings Destructuring Destructuring allows binding using pattern matching, with support for matching arrays and objects. Destructuring is fail-soft, similar to standard object lookup foo["bar"], producing undefined values when not found.// list matching var [a, , b] = [1,2,3]; // object matching var { op: a, lhs: { op: b }, rhs: c } = getASTNode() // object matching shorthand // binds `op`, `lhs` and `rhs` in scope var {op, lhs, rhs} = getASTNode() // Can be used in parameter position function g({name: x}) { console.log(x); } g({name: 5}) // Fail-soft destructuring var [a] = []; a === undefined; // Fail-soft destructuring with defaults var [a = 1] = []; a === 1; More info: MDN Destructuring assignment Default + Rest + Spread Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments and addresses common cases more directly. function f(x, y=12) { // y is 12 if not passed (or passed as undefined) return x + y; } f(3) == 15 function f(x, ...y) { // y is an Array return x * y.length; } f(3, "hello", true) == 6 function f(x, y, z) { return x + y + z; } // Pass each elem of array as argument f(...[1,2,3]) == 6 More MDN info: Default parameters, Rest parameters, Spread Operator Let + Const Block-scoped binding constructs. let is the new var. const is single-assignment. Static restrictions prevent use before assignment. function f() { { let x; { // okay, block scoped name const x = "sneaky"; // error, const x = "foo"; } // error, already declared in block let x = "inner"; } } More MDN info: let statement, const statement Iterators + For..Of Iterator objects enable custom iteration like CLR IEnumerable or Java Iterable. Generalize for..in to custom iterator-based iteration with for..of. Don't require realizing an array, enabling lazy design patterns like LINQ. let fibonacci = { [Symbol.iterator]() { let pre = 0, cur = 1; return { next() { [pre, cur] = [cur, pre + cur]; return { done: false, value: cur } } } } } for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; console.log(n); } Iteration is based on these duck-typed interfaces (using TypeScript type syntax for exposition only): interface IteratorResult { done: boolean; value: any; } interface Iterator { next(): IteratorResult; } interface Iterable { [Symbol.iterator](): Iterator } More info: MDN for...of Generators Generators simplify iterator-authoring using function* and yield. A function declared as function* returns a Generator instance. Generators are subtypes of iterators which include additional next and throw. These enable values to flow back into the generator, so yield is an expression form which returns a value (or throws). Note: Can also be used to enable 'await'-like async programming, see also ES7 await proposal. var fibonacci = { [Symbol.iterator]: function*() { var pre = 0, cur = 1; for (;;) { var temp = pre; pre = cur; cur += temp; yield cur; } } } for (var n of fibonacci) { // truncate the sequence at 1000 if (n > 1000) break; console.log(n); } The generator interface is (using TypeScript type syntax for exposition only): interface Generator extends Iterator { next(value?: any): IteratorResult; throw(exception: any); } More info: MDN Iteration protocols Unicode Non-breaking additions to support full Unicode, including new Unicode literal form in strings and new RegExp u mode to handle code points, as well as new APIs to process strings at the 21bit code points level. These additions support building global apps in JavaScript.// same as ES5.1 "𠮷".length == 2 // new RegExp behaviour, opt-in 'u' "𠮷".match(/./u)[0].length == 2 // new form "\u{20BB7}"=="𠮷"=="\uD842\uDFB7" // new String ops "𠮷".codePointAt(0) == 0x20BB7 // for-of iterates code points for(var c of "𠮷") { console.log(c); } More info: MDN RegExp.prototype.unicode Modules Language-level support for modules for component definition. Codifies patterns from popular JavaScript module loaders (AMD, CommonJS). Runtime behaviour defined by a host-defined default loader. Implicitly async model – no code executes until requested modules are available and processed.// lib/math.js export function sum(x, y) { return x + y; } export var pi = 3.141593; // app.js import * as math from "lib/math"; alert("2π = " + math.sum(math.pi, math.pi)); // otherApp.js import {sum, pi} from "lib/math"; alert("2π = " + sum(pi, pi)); Some additional features include export default and export *:// lib/mathplusplus.js export * from "lib/math"; export var e = 2.71828182846; export default function(x) { return Math.log(x); } // app.js import ln, {pi, e} from "lib/mathplusplus"; alert("2π = " + ln(e)*pi*2); More MDN info: import statement, export statement Module Loaders Module loaders support: Dynamic loading State isolation Global namespace isolation Compilation hooks Nested virtualization The default module loader can be configured, and new loaders can be constructed to evaluate and load code in isolated or constrained contexts.// Dynamic loading – 'System' is default loader System.import('lib/math').then(function(m) { alert("2π = " + m.sum(m.pi, m.pi)); }); // Create execution sandboxes – new Loaders var loader = new Loader({ global: fixup(window) // replace 'console.log' }); loader.eval("console.log('hello world!');"); // Directly manipulate module cache System.get('jquery'); System.set('jquery', Module({$: $})); // WARNING: not yet finalized Map + Set + WeakMap + WeakSet Efficient data structures for common algorithms. WeakMaps provides leak-free object-key'd side tables.// Sets var s = new Set(); s.add("hello").add("goodbye").add("hello"); s.size === 2; s.has("hello") === true; // Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34; // Weak Maps var wm = new WeakMap(); wm.set(s, { extra: 42 }); wm.size === undefined // Weak Sets var ws = new WeakSet(); ws.add({ data: 42 }); // Because the added object has no other references, it will not be held in the set More MDN info: Map, Set, WeakMap, WeakSet Proxies Proxies enable creation of objects with the full range of behaviors available to host objects. Can be used for interception, object virtualization, logging/profiling, etc.// Proxying a normal object var target = {}; var handler = { get: function (receiver, name) { return `Hello, ${name}!`; } }; var p = new Proxy(target, handler); p.world === 'Hello, world!'; // Proxying a function object var target = function () { return 'I am the target'; }; var handler = { apply: function (receiver, ...args) { return 'I am the proxy'; } }; var p = new Proxy(target, handler); p() === 'I am the proxy'; There are traps available for all of the runtime-level meta-operations: var handler = { get:..., set:..., has:..., deleteProperty:..., apply:..., construct:..., getOwnPropertyDescriptor:..., defineProperty:..., getPrototypeOf:..., setPrototypeOf:..., enumerate:..., ownKeys:..., preventExtensions:..., isExtensible:... } More info: MDN Proxy Symbols Symbols enable access control for object state. Symbols allow properties to be keyed by either string (as in ES5) or symbol. Symbols are a new primitive type. Optional description parameter used in debugging - but is not part of identity. Symbols are unique (like gensym), but not private since they are exposed via reflection features like Object.getOwnPropertySymbols. var MyClass = (function() { // module scoped symbol var key = Symbol("key"); function MyClass(privateData) { this[key] = privateData; } MyClass.prototype = { doStuff: function() { ... this[key] ... } }; return MyClass; })(); var c = new MyClass("hello") c["key"] === undefined More info: MDN Symbol Subclassable Built-ins In ES6, built-ins like Array, Date and DOM Element s can be subclassed. Object construction for a function named Ctor now uses two-phases (both virtually dispatched): Call Ctor[@@create] to allocate the object, installing any special behavior Invoke constructor on new instance to initialize The known @@create symbol is available via Symbol.create. Built-ins now expose their @@create explicitly.// Pseudo-code of Array class Array { constructor(...args) { /* ... */ } static [Symbol.create]() { // Install special [[DefineOwnProperty]] // to magically update 'length' } } // User code of Array subclass class MyArray extends Array { constructor(...args) { super(...args); } } // Two-phase 'new': // 1) Call @@create to allocate object // 2) Invoke constructor on new instance var arr = new MyArray(); arr[1] = 12; arr.length == 2 Math + Number + String + Array + Object APIs Many new library additions, including core Math libraries, Array conversion helpers, String helpers, and Object.assign for copying. Number.EPSILON Number.isInteger(Infinity) // false Number.isNaN("NaN") // false Math.acosh(3) // 1.762747174039086 Math.hypot(3, 4) // 5 Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2 "abcde".includes("cd") // true "abc".repeat(3) // "abcabcabc" Array.from(document.querySelectorAll('*')) // Returns a real Array Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior [0, 0, 0].fill(7, 1) // [0,7,7] [1, 2, 3].find(x => x == 3) // 3 [1, 2, 3].findIndex(x => x == 2) // 1 [1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2] ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"] ["a", "b", "c"].keys() // iterator 0, 1, 2 ["a", "b", "c"].values() // iterator "a", "b", "c" Object.assign(Point, { origin: new Point(0,0) }) More MDN info: Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign Binary and Octal Literals Two new numeric literal forms are added for binary ( b) and octal ( o). 0b111110111 === 503 // true 0o767 === 503 // true Promises Promises are a library for asynchronous programming. Promises are a first class representation of a value that may be made available in the future. Promises are used in many existing JavaScript libraries. function timeout(duration = 0) { return new Promise((resolve, reject) => { setTimeout(resolve, duration); }) } var p = timeout(1000).then(() => { return timeout(2000); }).then(() => { throw new Error("hmm"); }).catch(err => { return Promise.all([timeout(100), timeout(200)]); }) More info: MDN Promise Reflect API Full reflection API exposing the runtime-level meta-operations on objects. This is effectively the inverse of the Proxy API, and allows making calls corresponding to the same meta-operations as the proxy traps. Especially useful for implementing proxies.// No sample yet More info: MDN Reflect Tail Calls Calls in tail-position are guaranteed to not grow the stack unboundedly. Makes recursive algorithms safe in the face of unbounded inputs. function factorial(n, acc = 1) { 'use strict'; if (n <= 1) return acc; return factorial(n - 1, n * acc); } // Stack overflow in most implementations today, // but safe on arbitrary inputs in ES6 factorial(100000)
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Data Structures Docs Data Structures are a specialized means of organizing and storing data in computers in such a way that we can perform operations on the stored data more efficiently. Data structures have a wide and diverse scope of usage across the fields of Computer Science and Software Engineering.Image by author Data structures are being used in almost every program or software system that has been developed. Moreover, data structures come under the fundamentals of Computer Science and Software Engineering. It is a key topic when it comes to Software Engineering interview questions. Hence as developers, we must have good knowledge about data structures. In this article, I will be briefly explaining 8 commonly used data structures every programmer must know.{% embed url=" https://replit.com/@bgoonz/DATASTRUCTURES-NOTES\#sorting/insertion\_sort/insertion.py" %} 1. Arrays An array is a structure of fixed-size, which can hold items of the same data type. It can be an array of integers, an array of floating-point numbers, an array of strings or even an array of arrays (such as 2-dimensional arrays). Arrays are indexed, meaning that random access is possible. Fig 1. Visualization of basic Terminology of Arrays (Image by author) Array operations Traverse: Go through the elements and print them. Search: Search for an element in the array. You can search the element by its value or its index Update: Update the value of an existing element at a given index Inserting elements to an array and deleting elements from an array cannot be done straight away as arrays are fixed in size. If you want to insert an element to an array, first you will have to create a new array with increased size (current size + 1), copy the existing elements and add the new element. The same goes for the deletion with a new array of reduced size. Applications of arrays Used as the building blocks to build other data structures such as array lists, heaps, hash tables, vectors and matrices. Used for different sorting algorithms such as insertion sort, quick sort, bubble sort and merge sort. 2. Linked Lists A linked list is a sequential structure that consists of a sequence of items in linear order which are linked to each other. Hence, you have to access data sequentially and random access is not possible. Linked lists provide a simple and flexible representation of dynamic sets. Let's consider the following terms regarding linked lists. You can get a clear idea by referring to Figure 2. Elements in a linked list are known as nodes. Each node contains a key and a pointer to its successor node, known as next. The attribute named head points to the first element of the linked list. The last element of the linked list is known as the tail. Fig 2. Visualization of basic Terminology of Linked Lists (Image by author) Following are the various types of linked lists available. Singly linked list — Traversal of items can be done in the forward direction only. Doubly linked list — Traversal of items can be done in both forward and backward directions. Nodes consist of an additional pointer known as prev, pointing to the previous node. Circular linked lists — Linked lists where the prev pointer of the head points to the tail and the next pointer of the tail points to the head. Linked list operations Search: Find the first element with the key k in the given linked list by a simple linear search and returns a pointer to this element Insert: Insert a key to the linked list. An insertion can be done in 3 different ways; insert at the beginning of the list, insert at the end of the list and insert in the middle of the list. Delete: Removes an element x from a given linked list. You cannot delete a node by a single step. A deletion can be done in 3 different ways; delete from the beginning of the list, delete from the end of the list and delete from the middle of the list. Applications of linked lists Used for symbol table management in compiler design. Used in switching between programs using Alt + Tab (implemented using Circular Linked List). 3. Stacks A stack is a LIFO (Last In First Out — the element placed at last can be accessed at first) structure which can be commonly found in many programming languages. This structure is named as “stack” because it resembles a real-world stack — a stack of plates.Image by congerdesign from Pixabay Stack operations Given below are the 2 basic operations that can be performed on a stack. Please refer to Figure 3 to get a better understanding of the stack operations. Push: Insert an element on to the top of the stack. Pop: Delete the topmost element and return it. Fig 3. Visualization of basic Operations of Stacks (Image by author) Furthermore, the following additional functions are provided for a stack in order to check its status. Peek: Return the top element of the stack without deleting it. isEmpty: Check if the stack is empty. isFull: Check if the stack is full. Applications of stacks Used for expression evaluation (e.g.: shunting-yard algorithm for parsing and evaluating mathematical expressions). Used to implement function calls in recursion programming. 4. Queues A queue is a FIFO (First In First Out — the element placed at first can be accessed at first) structure which can be commonly found in many programming languages. This structure is named as “queue” because it resembles a real-world queue — people waiting in a queue. Image by Sabine Felidae from Pixabay Queue operations Given below are the 2 basic operations that can be performed on a queue. Please refer to Figure 4 to get a better understanding of the queue operations. Enqueue: Insert an element to the end of the queue. Dequeue: Delete the element from the beginning of the queue. Fig 4. Visualization of Basic Operations of Queues (Image by author) Applications of queues Used to manage threads in multithreading. Used to implement queuing systems (e.g.: priority queues). 5. Hash Tables A Hash Table is a data structure that stores values which have keys associated with each of them. Furthermore, it supports lookup efficiently if we know the key associated with the value. Hence it is very efficient in inserting and searching, irrespective of the size of the data. Direct Addressing uses the one-to-one mapping between the values and keys when storing in a table. However, there is a problem with this approach when there is a large number of key-value pairs. The table will be huge with so many records and may be impractical or even impossible to be stored, given the memory available on a typical computer. To avoid this issue we use hash tables. Hash Function A special function named as the hash function ( h) is used to overcome the aforementioned problem in direct addressing. In direct accessing, a value with key k is stored in the slot k. Using the hash function, we calculate the index of the table (slot) to which each value goes. The value calculated using the hash function for a given key is called the hash value which indicates the index of the table to which the value is mapped. h(k) = k % m h: Hash function k: Key of which the hash value should be determined m: Size of the hash table (number of slots available). A prime value that is not close to an exact power of 2 is a good choice for m. Fig 5. Representation of a Hash Function (Image by author) Consider the hash function h(k) = k % 20, where the size of the hash table is 20. Given a set of keys, we want to calculate the hash value of each to determine the index where it should go in the hash table. Consider we have the following keys, the hash and the hash table index. 1 → 1%20 → 1 5 → 5%20 → 5 23 → 23%20 → 3 63 → 63%20 → 3 From the last two examples given above, we can see that collision can arise when the hash function generates the same index for more than one key. We can resolve collisions by selecting a suitable hash function h and use techniques such as chaining and open addressing. Applications of hash tables Used to implement database indexes. Used to implement associative arrays. Used to implement the “set” data structure. 6. Trees A tree is a hierarchical structure where data is organized hierarchically and are linked together. This structure is different from a linked list whereas, in a linked list, items are linked in a linear order. Various types of trees have been developed throughout the past decades, in order to suit certain applications and meet certain constraints. Some examples are binary search tree, B tree, treap, red-black tree, splay tree, AVL tree and n-ary tree. Binary Search Trees A binary search tree (BST), as the name suggests, is a binary tree where data is organized in a hierarchical structure. This data structure stores values in sorted order. Every node in a binary search tree comprises the following attributes. key: The value stored in the node. left: The pointer to the left child. right: The pointer to the right child. p: The pointer to the parent node. A binary search tree exhibits a unique property that distinguishes it from other trees. This property is known as the binary-search-tree property. Let x be a node in a binary search tree. If y is a node in the left subtree of x, then y.key ≤ x.key If y is a node in the right subtree of x, then y.key ≥ x.key Fig 6. Visualization of Basic Terminology of Trees (Image by author) Applications of trees Binary Trees: Used to implement expression parsers and expression solvers. Binary Search Tree: used in many search applications where data are constantly entering and leaving. Heaps: used by JVM (Java Virtual Machine) to store Java objects. Treaps: used in wireless networking. Check my articles below on 8 useful tree data structures and self-balancing binary search trees. 8 Useful Tree Data Structures Worth KnowingAn overview of 8 different tree data structurestowardsdatascience.com Self-Balancing Binary Search Trees 101Introduction to Self-Balancing Binary Search Treestowardsdatascience.com 7. Heaps A Heap is a special case of a binary tree where the parent nodes are compared to their children with their values and are arranged accordingly. Let us see how we can represent heaps. Heaps can be represented using trees as well as arrays. Figures 7 and 8 show how we can represent a binary heap using a binary tree and an array. Fig 7. Binary Tree Representation of a Heap (Image by author) Fig 8. Array Representation of a Heap (Image by author) Heaps can be of 2 types. Min Heap — the key of the parent is less than or equal to those of its children. This is called the min-heap property. The root will contain the minimum value of the heap. Max Heap — the key of the parent is greater than or equal to those of its children. This is called the max-heap property. The root will contain the maximum value of the heap. Applications of heaps Used in heapsort algorithm. Used to implement priority queues as the priority values can be ordered according to the heap property where the heap can be implemented using an array. Queue functions can be implemented using heaps within O(log n) time. Used to find the kᵗʰ smallest (or largest) value in a given array. Check my article below on implementing a heap using the python heapq module. Introduction to Python Heapq ModuleA simple introduction on how to use Python's heapq moduletowardsdatascience.com 8. Graphs A graph consists of a finite set of vertices or nodes and a set of edges connecting these vertices. The order of a graph is the number of vertices in the graph. The size of a graph is the number of edges in the graph. Two nodes are said to be adjacent if they are connected to each other by the same edge. Directed Graphs A graph G is said to be a directed graph if all its edges have a direction indicating what is the start vertex and what is the end vertex. We say that (u, v) is incident from or leaves vertex u and is incident to or enters vertex v. Self-loops: Edges from a vertex to itself. Undirected Graphs A graph G is said to be an undirected graph if all its edges have no direction. It can go in both ways between the two vertices. If a vertex is not connected to any other node in the graph, it is said to be isolated. Fig 9. Visualization of Terminology of Graphs (Image by author) You can read more about graph algorithms from my article 10 Graph Algorithms Visually Explained. 10 Graph Algorithms Visually ExplainedA quick introduction to 10 basic graph algorithms with examples and visualisationsmedium.com Applications of graphs Used to represent social media networks. Each user is a vertex, and when users connect they create an edge. Used to represent web pages and links by search engines. Web pages on the internet are linked to each other by hyperlinks. Each page is a vertex and the hyperlink between two pages is an edge. Used for Page Ranking in Google. Used to represent locations and routes in GPS. Locations are vertices and the routes connecting locations are edges. Used to calculate the shortest route between two locations.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Learn Css Learn CSS This is an embedded Microsoft Office presentation, powered by Office. CSS Selectors Learn CSS So That Your Site Doesn't Look Like Garbage CSS Selectors CSS Selector : Applies styles to a specific DOM element(s), there are various types: Type Selectors : Matches by node name. Class Selectors : Matches by class name. ID Selectors : Matches by ID name. Universal Selectors : Selects all HTML elements on a page. Attribute Selectors : Matches elements based on the prescence or value of a given attribute. (i.e. a[title] will match all a elements with a title attribute)/* Type selector */ div { background-color: #000000; }/* Class selector */ .active { color: #ffffff; }/* ID selector */ #list-1 { border: 1px solid gray; }/* Universal selector */ * { padding: 10px; }/* Attribute selector */ a[title] { font-size: 2em; } Class Selectors Used to select all elements of a certain class denoted with a .[class name] You can assign multiple classes to a DOM element by separating them with a space. Compound Class Selectors To get around accidentally selecting elements with multiple classes beyond what we want to grab we can chain dots. TO use a compound class selector just append the classes together when referencing them in the CSS.<div class="box yellow"></div> <div class="box orange"></div> <div class="circle orange"></div> i.e. .box.yellow will select only the first element. KEEP IN MIND that if you do include a space it will make the selector into a descendant selector. h1#heading, h2.subheading { font-style: italic; } When we want to target all h1 tags with the id of heading. CSS Combinators CSS Combinators are used to combine other selectors into more complex or targeted selectors — they are very powerful! Be careful not to use too many of them as they will make your CSS far too complex. Descendant Selectors Separated by a space. Selects all descendants of a parent container. Direct Child Selectors Indicated with a >. Different from descendants because it only affects the direct children of an element..menu > .is-active { background-color: #ffe0b2; }<body> <div class="menu"> <div class="is-active">Belka</div> <div> <div class="is-active">Strelka</div> </div> </div> </body> <div class="is-active"> Laika </div> </body> Belka would be the only element selected. Adjacent Sibling Selectors Uses the + symbol. Used for elements that directly follow one another and who both have the same parent. h1 + h2 { font-style: italic; } <h1>Big header</h1> <h2>This one is styled because it is directly adjacent to the H1</h2> <h2>This one is NOT styled because there is no H1 right before it</h2> Pseudo-Classes Pseudo-Class : Specifies a special state of the seleted element(s) and does not refer to any elements or attributes contained in the DOM. Format is a Selector:Pseudo-Class Name or A:B a:hover { font-family: "Roboto Condensed", sans-serif; color: #4fc3f7; text-decoration: none; border-bottom: 2px solid #4fc3f7; } Some common pseudo-classes that are frequently used are: active : 'push down', when ele are activated. checked : applies to things like radio buttons or checkbox inputs. disabled : any disabled element. first-child : first element in a group of children/siblings. focus : elements that have current focus. hover : elements that have cursor hovering over it. invalid : any form elements in an invalid state from client-side form validation. last-child : last element in a group of children/siblings. not(selector) : elements that do not match the provided selector. required : form elements that are required. valid : form elements in a valid state. visited : anchor tags of whih the user has already been to the URL that the href points to. Pseudo-Selectors Used to create pseudo-elements as children of the elements to which the property applies.::after::before<style> p::before { background-color: lightblue; border-right: 4px solid violet; content: ":-) "; margin-right: 4px; padding-left: 4px; } </style> <p>This is the first paragraph</p> <p>This is the second paragraph</p> <p>This is the third paragraph</p> Will add some blue smiley faces before the p tag elements. CSS Rules CSS Rule : Collection of single or compound selectors, a curly brace, zero or more properties CSS Rule Specificity : Sometimes CSS rules will contain multiple elements and may have overlapping properties rules for those same elements - there is an algorithm in CSS that calculates which rule takes precedence. The Four Number Calculation : listed in increasing order of importance. Who has the most IDs? If no one, continue. Who has the most classes? If no one, continue. Who has the most tags? If no one, continue. Last Read in the browser wins. Coming back to our example where all the CSS Rules have tied, the last step 4 wins out so our element will have a purple border. CSS: Type, Properties, and Imports Typography font-family : change the font.- Remember that not all computers have the same fonts on them. - You can import web fonts via an api by using - `@import url('https://fonts.googleapis.com/css2?family=Liu+Jian+Mao+Cao&display=swap');` and pasting it st the top of your CSS file. - And then reference it in your font-family. - `font-size` : Changes the size of your font. - Keep in mind the two kind of units CSS uses: - `Absolute` : `Pixels`, Points, Inches, Centimeters. - `Relative` : Em, Rem. - Em: Calulating the size relative to the previous div (bubbles down) - Rem: Calulates relative to the parent element always. - `font-style` : Used to set a font to italics. - `font-weight` : Used to make a font bold. - `text-align` : Used to align your text to the left, center, or right. - `text-decoration` : Use to put lines above, through, or under text. Lines can be solid, dashed, or wavy! - `text-transform` : Used to set text to all lowercase, uppercase, or capitalize all words. Background-Images You can use the background-image property to set a background image for an element. CSS: Colors, Borders, and Shadows Colors You can set colors in CSS in three popular ways: by name, by hexadecimal RGB value, and by their decimal RGB value. rgba() is used to make an rbg value more transparent, the a is used to specify the alpha channel. Color : Property used to change the color of text. Background-Color : Property to change the backgrounf color of an element. Borders Borders take three values: The width of the border, the style (i.e. solid, dotted, dashed), color of the border. Shadows There are two kinds of shadows in CSS: box shadows and text shadows. Box refers to HTML elements. Text refers to text. Shadows take values such as, the horizontal & vertical offsets of the shadow, the blur radius of the shadow, the spread radius, and of course the colors. The Box Model Box Model : A concept that basically boils down that every DOM element has a box around it. Imagine a gift, inside is the gift, wrapped in foam all around (padding), and the giftbox outside of it (border) and then a wrapping paper on the giftbox (margin).- For items that are using block as it's display, the browser will follow these rules to layout the element: - The box fills 100% of the available container space. - Every new box takes on a new line/row. - Width and Height properties are respected. - Padding, Margin, and Border will push other elements away from the box. - Certain elements have block as their default display, such as: divs, headers, and paragraphs.- For items that are using inline as it's display, the browser will follow these rules to layout the element: - Each box appears in a single line until it fills up the space. - Width and height are not respected. - Padding, Margin, and Border are applied but they do not push other elements away from the box. - Certain elements have inline as their default display, such as: span tags, anchors, and images. Standard Box Model vs Border-Box- As per the standard Box Model, the width and height pertains to the content of the box and excludes any additional padding, borders, and margins. This bothered many programmers so they created the border box to include the calculation of the entire box's height and width. Inline-Block- Inline-block uses the best features of both block and inline. - Elements still get laid out left to right. - Layout takes into account specified width and height. Padding- Padding applies padding to every side of a box. It is shorthand for four padding properties in this order: padding-top, padding-right, padding-bottom, padding-left (clockwise!) Border- Border applies a border on all sides of an element. It takes three values in this order: border-width, border-style, border-color. - All three properties can be broken down in the four sides clockwise: top, right, bottom, left. Margin- Margin sets margins on every side of an element. It takes four values in this order: margin-top, margin-right, margin-bottom, margin-left. - You can use margin: 0 auto to center an element. Positioning The position property allows us to set the position of elements on a page and is an integral part of creatnig a Web page layout. It accepts five values: static, relative, absolute, fixed, sticky. Every property (minus static) is used with: top, right, bottom, and left to position an element on a page. Static Positioning The default position value of page elements. Most likely will not use static that much. Relative Positioning Remains in it's original position in the page flow. It is positioned RELATIVE to the it's ORIGINAL PLACE on the page flow. Creates a stacking context : overlapping elements whose order can be set by the z-index property.#pink-box { background-color: #ff69b4; bottom: 0; left: -20px; position: relative; right: 0; top: 0; } **Absolute Positioning** Absolute elements are removed from the normal page flow and other elements around it act like it's not there. (how we can easily achieve some layering) Here are some examples to illustration absolute positioning:.container { background-color: #2b2d2f; position: relative; }#pink-box { position: absolute; top: 60px; } - Note that the container ele has a relative positioning — this is so that any changes made to the absolute positioned children will be positioned from it's top-left corner. - Note that because we removed the pink from the normal page flow, the container has now shifted the blue box to where the pink box should have been — which is why it is now layered beneath the pink..container { background-color: #2b2d2f; position: relative; }#pink-box { position: absolute; top: 60px; }#blue-box { position: absolute; } - As you can see here, since we have also taken the blue box out of the normal page flow by declaring it as absoutely positioned it now overlaps over the pink box..container { background-color: #2b2d2f; position: relative; }#pink-box { background-color: #ff69b4; bottom: 60px; position: absolute; } - Example where the absolute element has it's bottom property modified..container { background-color: #2b2d2f; }#pink-box { background-color: #ff69b4; bottom: 60px; position: absolute; } - If we removed the container's relative position. Our absolute unit would look for the nearest parent which would be the document itself. Fixed Positioning Another positioning that removes it's element from the page flow, and automatically positions it's parent as the HTML doc itself. Fixed also uses top, right, bottom, and left. Useful for things like nav bars or other features we want to keep visible as the user scrolls. Sticky Positioning Remains in it's original position in the page flow, and it is positioned relative to it's closest block-level ancestor and any scrolling ancestors. Behaves like a relatively positioned element until the point at which you would normally scroll past it's viewport — then it sticks! It is positioned with top, right, bottom, and left. A good example are headers in a scrollable list. Flexible Box Model Flexbox is a CSS module that provides a convenient way for us to display items inside a flexible container so that the layout is responsive. Float was used back in the day to display position of elements in a container. A very inconvenient aspect of float is the need to clear the float. To 'clear' a float we need to set up a ghost div to properly align — this is already sounds so inefficient. Using Flexbox Flexbox automatically resizes a container element to fit the viewport size without needing to use breakpoints.- Flexbox layout applies styles to the parent element, and it's children..container { display: flex; /*sets display to use flex*/ flex-wrap: wrap; /*bc flex tries to fit everything into one line, use wrap to have the elements wrap to the next line*/ flex-direction: row; /*lets us create either rows or columns*/ } flex-flow can be used to combine wrap and direction. justify-content used to define the alignment of flex items along the main axis. align-items used to define the alignment on the Y-axis. align-content redistributes extra space on the cross axis. By default, flex items will appear in the order they are added to the DOM, but we can use the order property to change that. Some other properties we can use on flex items are: flex-grow : dictates amount of avail. space the item should take up. flex-shrink : defines the ability for a flex item to shrink. flex-basis : Default size of an element before the remaining space is distributed. flex : shorthand for grow, shrink and basis. align-self : Overrides default alignment in the container. Grid Layout CSS Grid is a 2d layout system that let's use create a grid with columns and rows purely using Vanilla CSS. (flex is one dimensional) Bootstrap vs CSS Grid Bootstrap was a front-end library commonly used to create grid layouts but now CSS grid provides greater flexibility and control. Grid applies style to a parent container and it's child elements..grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto; grid-template-areas: "header header header" "main . sidebar" "footer footer footer"; grid-column-gap: 20px; grid-row-gap: 30px; justify-items: stretch; align-items: stretch; justify-content: stretch; align-content: stretch; }.item-1 { grid-area: header; } .item-2 { grid-area: main; } .item-3 { grid-area: sidebar; } .item-4 { grid-area: footer; } Columns and Rows can be defined with: pixels, percentages, auto, named grid lines, using repeat, fractions. Grid Template Areas gives us a handy way to map out and visualize areas of the grid layout. Combine areas with templates to define how much space an area should take up. Grid Gaps can be used to create 'gutters' between grid item.s The way we have defined our grid with grid-templates and areas are considered explicit. We can also implicitly define grids..grid-container { display: grid; grid-template-columns: 100px 100px 100px 100px; grid-template-rows: 50px 50px 50px; grid-auto-columns: 100px; grid-auto-rows: 50px; } Any grid items that aren't explicity placed are automatically placed or re-flowed Spanning Columns & Rows We can use the following properties to take up a specified num of cols and rows. grid-column-start grid-column-end grid-row-start grid-row-end All four properties can take any of the following values: the line number, span #, span name, auto..item-1 { grid-row-start: row2-start; /* Item starts at row line named "row2-start" */ grid-row-end: 5; /* Item ends at row line 5 */ grid-column-start: 1; /* Item starts at column line 1 */ grid-column-end: three; /* Item ends at column line named "three" */ }.item-2 { grid-row-start: 1; /* Item starts at row line 1 */ grid-row-end: span 2; /* Item spans two rows and ends at row line 3 */ grid-column-start: 3; /* Item starts at column line 3 */ grid-column-end: span col5-start; /* Item spans and ends at line named "col5-start" */ } Grid Areas We use the grid areas in conjunction with grid-container property to define sections of the layout. We can then assign named sections to individual element's css rules. Justify & Align Self Justify items and Align Items can be used to align all grid items at once. Justify Self is used to align self on the row. It can take four values: start, end, center, stretch. Align Self is used to align self on the column. It can take four values: start, end, center, stretch. CSS Hover Effect and Handling Overflow css .btn { background-color: #00bfff; color: #ffffff; border-radius: 10px; padding: 1.5rem; }.btn--active:hover { cursor: pointer; transform: translateY(-0.25rem);/* Moves our button up/down on the Y axis */ } The Pseudo Class Selector hover activates when the cursor goes over the selected element. Content Overflow- You can apply an overflow content property to an element if it's inner contents are spilling over. There are three members in the overflow family: — overflow-x : Apply horizontally. - overflow-y : Apply vertically. - overflow : Apply both directions. Transitions Transitions provide a way to control animation speed when changing CSS properties. Implicit Transitions : Animations that involve transitioning between two states. Defining Transitions transition-property : specifies the name of the CSS property to apply the transition. transition-duration : during of the transition. transition-delay : time before the transition should start. Examples :#delay { font-size: 14px; transition-property: font-size; transition-duration: 4s; transition-delay: 2s; }#delay:hover { font-size: 36px; } - After a delay of two seconds, a four second transition begins where the font size goes from 36px to 14px..box { border-style: solid; border-width: 1px; display: block; width: 100px; height: 100px; background-color: #0000ff; transition: width 2s, height 2s, background-color 2s, transform 2s; }.box:hover { background-color: #ffcccc; width: 200px; height: 200px; transform: rotate(180deg); } - When the mouse hovers over a box, it spins due to the rotate transform. Width and height change and also the bg color. BEM Guidelines BEM was created as a guideline to solve the issue of loose standards around CSS naming conventions. BEM stands for block, element, modifier. Block A standalone entity that is meaningful on it's own. Can be nested and interact with one another. Holistic entities without DOM rep can be blocks. May consist latin letters, digits, and dashes. Any DOM node can be a block if it accepts a class name. Element Part of a block and has no standalone meaning. Any element that is semantically tied to a block. May consist latin letters, digits, and dashes. Formed by using two underscores after it's block name. Any DOM node within a block can be an element. Element classes should be used independently. Modifier A flag on blocks or elements. Use them to change appearance, behavior or state. Extra class name to add onto blocks or elements. Add mods only to the elements they modify. Modifier names may consist of Latin letters, digits, dashes and underscores. Written with two dashes. BEM Example<form class="form form--theme-xmas form--simple"> <input class="form__input" type="text" /> <input class="form__submit form__submit--disabled" type="submit" /> </form>/* block selector */ .form { }/* block modifier selector */ .form--theme-xmas { }/* block modifier selector */ .form--simple { }/* element selector */ .form__input { }/* element selector */ .form__submit { }/* element modifier selector */ .form__submit--disabled { } If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz's gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com Or Checkout my personal Resource Site: a/A-Student-Resources Edit description goofy-euclid-1cd736.netlify.app By Bryan Guner on March 6, 2021.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Useful Snippets A list of all of my articles to link to future posts Scope, Closures & Context In JavaScript"JavaScript's global scope is like a public toilet. You can't avoid going in there, but try to limit your contact with... bryanguner.medium.com Fundamental Javascript Concepts You Should Understand Plain Old JS Object Lesson Concepts bryanguner.medium.com Mutability And Reference VS Privative Types in JavaScript Mutability && Primitive && Reference Examples bryanguner.medium.com Array Callback Methods Implemented With For Loops How to implement array callback methods in JavaScript javascript.plainenglish.io JavaScript in Plain English New JavaScript and Web Development articles every day. javascript.plainenglish.io Beginner's Guide To React Part 2 As I learn to build web applications in React I will blog about it in this series in an attempt to capture the... bryanguner.medium.com A Very Quick Guide To Calculating Big O Computational Complexity Big O: big picture, broad strokes, not details bryanguner.medium.com Introduction to React for Complete Beginners All of the code examples below will be included a second time at the bottom of this article as an embedded gist. javascript.plainenglish.io Scheduling: setTimeout and setInterval We may decide to execute a function not right now, but at a later time. That's called "scheduling a call". javascript.plainenglish.io LocalStorage VS SessionStorage Web storage objects localStorage and sessionStorage allow to save key/value pairs in the browser. bryanguner.medium.com These Are The Bash Shell Commands That Stand Between Me And Insanity. I will not profess to be a bash shell wizard... but I have managed to scour some pretty helpful little scripts from Stack... bryanguner.medium.com How To Implement Native(ES6) Data Structures Using Arrays & Objects Smart data structures and dumb code works better than the other way around -"Eric S. Raymond" bryanguner.medium.com Objects in Javascript Codepen with examples for you to practice with below! medium.com The Beginner's Guide To JavaScript Part 1 javascript.plainenglish.io Web Developer Resource List Part 4 A all encompassing list of tools and resources for web developers medium.com Star Gazers The place that enthusiastic and stargazer to everything. medium.com VSCode Extensions Specifically for JavaScript Development VSCode Extensions that are indispensable in JavaScript development medium.com Fundamental Data Structures in JavaScript A simple to follow guide to Lists Stacks and Queues, with animated gifs, diagrams, and code examples! javascript.plainenglish.io Web Development Resources Part 3 I'm the psychological equivalent of a physical hoarder only instead of empty soda cans and dead racoons it's lists of... bryanguner.medium.com Web Development Interview Part 3💻 This installment is going to be the least technically demanding thus far however these questions are a more realistic... medium.com The Best Cloud-Based Code Playgrounds of 2021 (Part 1) A plethora of front-end code playgrounds have appeared over the years. They offer a convenient way to experiment with... bryanguner.medium.com Front End Interview Questions Part 2 These will focus more on vocabulary and concepts than the application driven approach in my last post! medium.com Web Developer Resource List Part 2 Because I compile these things compulsively anyway... medium.com HTTP Basics"If you want to build a ship, don't drum up the men and women to gather wood, divide the work, and give orders... levelup.gitconnected.com JavaScript Frameworks & Libraries My Awesome JavaScript List Part 2 javascript.plainenglish.io My 'awesome' list of JavaScript resources Everyone's seen the 'Awesome' lists on GitHub... and they are indeed awesome... so today I am going to attempt to curate my... javascript.plainenglish.io Everything You Need to Get Started With VSCode + Extensions & Resources Commands: levelup.gitconnected.com My Favorite VSCode Themes Themeslevelup.gitconnected.com Object Oriented Programming in JavaScript Object-Oriented Programming levelup.gitconnected.com JavaScript Rotate (Array) ProblemWalkthrough Explanation for Rotate Right medium.com Bryan Guner - Medium A plethora of front-end code playgrounds have appeared over the years. They offer a convenient way to experiment with... bryanguner.medium.com Postgresql Cheat Sheet PostgreSQL commands medium.com Everything You Need to Get Started With VSCode + Extensions & Resources Commands: levelup.gitconnected.com Super Simple Intro To HTML What is HTML, CSS & JS and why do we need all three? levelup.gitconnected.com Understanding Git (A Beginners Guide Containing Cheat Sheets & Resources) Basic Git Work Flow. levelup.gitconnected.com Git-Tricks Refs bryanguner.medium.com A Quick Guide to Big-O Notation, Memoization, Tabulation, and Sorting Algorithms by Example Curating Complexity: A Guide to Big-O Notation medium.com Python Study Guide for a JavaScript Programmer A guide to commands in Python from what you know in JavaScript levelup.gitconnected.com Lists Stacks and Queue's In JavaScript A simple to follow guide to these fundamental data structures with animated gifs, diagrams, and code examples! bryanguner.medium.com Web Development Resources Part 3 I'm the psychological equivalent of a physical hoarder only instead of empty soda cans and dead racoons it's lists of... bryanguner.medium.com My 'awesome' list of JavaScript resources Everyone's seen the 'Awesome' lists on GitHub... and they are indeed awesome... so today I am going to attempt to curate my... javascript.plainenglish.io Web Developer Resource List Part 2 Because I compile these things compulsively anyway... medium.com Web Development Interview Part 3💻 This installment is going to be the least technically demanding thus far however these questions are a more realistic... bryanguner.medium.com The Web Developer's Technical Interview Questions....Answers... and links to the missing pieces. medium.com Front End Interview Questions Part 2 These will focus more on vocabulary and concepts than the application driven approach in my last post! medium.com Running List Of Interesting Articles, Tools and Ideas... as I Explore Them Translation if you read this today (3/21/2021) it will be exceedingly short... because it's just gonna accumulate entries... bryanguner.medium.com The Best Cloud-Based Code Playgrounds of 2021 (Part 1) A plethora of front-end code playgrounds have appeared over the years. They offer a convenient way to experiment with... bryanguner.medium.com Fundamental Data Structures In JavaScript Data structures in JavaScript medium.com HTTP Basics"If you want to build a ship, don't drum up the men and women to gather wood, divide the work, and give orders... levelup.gitconnected.com JavaScript Frameworks & Libraries My Awesome JavaScript List Part 2 javascript.plainenglish.io bgoonz/Cumulative-Resource-List List of useful cheatsheets Inspired by @sindresorhus awesome and improved by these amazing contributors . If you see a... github.com My Favorite VSCode Themes Themeslevelup.gitconnected.com JavaScript Rotate (Array) ProblemWalkthrough Explanation for Rotate Right medium.com Everything You Need To Know About Relational Databases, SQL, PostgreSQL and Sequelize To Build... For Front end developers who like myself struggle with making the jump to fullstack. bryanguner.medium.com The Complete JavaScript Reference Guide You will want to bookmark this javascript.plainenglish.io Modules in Javascript Differences between Node.js and browsers medium.com An Introduction to Markdown (Bonus Markdown Templates Included) Basic Syntax Guide levelup.gitconnected.com Web Dev Resources Web Development levelup.gitconnected.com Regular Expressions description: medium.com A Collection of my most useful Gist Entries This list is in no particular order! bryanguner.medium.com VsCode Extension Readme Compilation Markdown PDF bryanguner.medium.com Learn CSS So That Your Site Doesn't Look Like Garbage CSS Selectors javascript.plainenglish.io PostgreSQL Setup For Windows & WSL/Ubuntu If you follow this guide to a tee... you will install PostgreSQL itself on your Windows installation. Then, you will... bryanguner.medium.com Emmet Cheat Sheet EMMET bryanguner.medium.com Express Quick Sheet Settings bryanguner.medium.com Deploy React App To Heroku Using Postgres & Express Heroku is an web application that makes deploying applications easy for a beginner. bryanguner.medium.com Basic Web Development Environment Setup Windows Subsystem for Linux (WSL) and Ubuntu levelup.gitconnected.com Fetch Quick Sheet Fetchbryanguner.medium.com By Bryan Guner on March 22, 2021. Canonical link Exported from Medium on July 13, 2021. view raw A-list-of-my-articles.md hosted with ❤ by GitHub A Very Quick Guide To Calculating Big O Computational Complexity Big O: big picture, broad strokes, not details A Very Quick Guide To Calculating Big O Computational Complexity Big O: big picture, broad strokes, not details For a more complete guide... checkout : A Quick Guide to Big-O Notation, Memoization, Tabulation, and Sorting Algorithms by Example Curating Complexity: A Guide to Big-O Notation medium.com way we analyze how efficient algorithms are without getting too mired in details - can model how much time any function will take given n inputs - interested in order of magnitude of number of the exact figure - O absorbs all fluff and n = biggest term - Big O of 3x^2 +x + 1 = O(n^2) Time Complexity no loops or exit & return = O(1) 0 nested loops = O(n) 1 nested loops = O(n^2) 2 nested loops = O(n^3) 3 nested loops = O(n^4) recursive: as you add more terms, increase in time as you add input diminishes recursion: when you define something in terms of itself, a function that calls itself used because of ability to maintain state at diffferent levels of recursion inherently carries large footprint every time function called, you add call to stack iterative: use loops instead of recursion (preferred) favor readability over performance O(n log(n)) & O(log(n)): dividing/halving if code employs recursion/divide-and-conquer strategy what power do i need to power my base to get n Time Definitions constant: does not scale with input, will take same amount of time for any input size n, constant time performs same number of operations every time logarithmic: increases number of operations it performs as logarithmic function of input size n function log n grows very slowly, so as n gets longer, number of operations the algorithm needs to perform doesn't increase very much halving linear: increases number of operations it performs as linear function of input size n number of additional operations needed to perform grows in direct proportion to increase in input size n log-linear: increases number of operations it performs as log-linear function of input size n looking over every element and doing work on each one quadratic: increases number of operations it performs as quadratic function of input size n exponential: increases number of operations it performs as exponential function of input size n number of nested loops increases as function of n polynomial: as size of input increases, runtime/space used will grow at a faster rate factorial: as size of input increases, runtime/space used will grow astronomically even with relatively small inputs rate of growth: how fast a function grows with input size Space Complexity How does the space usage scale/change as input gets very large? What auxiliary space does your algorithm use or is it in place (constant)? Runtime stack space counts as part of space complexity unless told otherwise. Sorting Algorithms Data Structures For similar content check out my GitHub: bgoonz - Overview _Web Developer, Electrical Engineer _ https://bryanguner.medium.com/ https://portfolio42.netlify.app/... github.com By Bryan Guner on May 19, 2021. Canonical link Exported from Medium on July 13, 2021. view raw A-Very-Qui.md hosted with ❤ by GitHub Array Callback Methods Implemented With For Loops How to implement array callback methods in JavaScript Array Callback Methods Implemented With For Loops How to implement array callback methods in JavaScript Functions are called "First Class Objects" in JavaScript because: A function is an instance of the Object type A function can have properties and has a link back to its constructor method You can store the function in a variable You can pass the function as a parameter to another function You can return the function from a function What do you think will be printed in the following: Anonymous callback, a named callback function foo(callback) { console.log('grape'); callback(); } function bar() { console.log('banana'); } const fruitBasket = function() { console.log('apple'); bar(); foo(bar); foo(function() { console.log('orange'); }); console.log('pear'); }; fruitBasket(); Function that takes in a value and two callbacks. The function should return the result of the callback who's invocation results in a larger value. function greaterValue(value, cb1, cb2) { // compare cb1 invoked with value to cb2 invoked with value // return the greater result let res1 = cb1(value); let res2 = cb2(value); if (res1 > res2) { // if this is false, we move out of if statement return res1; } return res2; } let negate = function(num) { return num * -1; }; let addOne = function(num) { return num + 1; }; console.log(greaterValue(3, negate, addOne)); console.log(greaterValue(-2, negate, addOne)); Note: we do not invoke negate or addOne (by using () to call them), we are passing the function itself. Write a function, myMap, that takes in an array and a callback as arguments. The function should mimic the behavior of Array.prototype.map. function myMap(arr, callback) { // iterate through the array, perform the cb on each element // return a new array with those new values let mapped = []; for (let i = 0; i < arr.length; i++) { // remember that map passes three args with each element. let val = callback(arr[i], i, arr); mapped.push(val); } return mapped; } let double = function(num) { return num * 2; }; console.log(myMap([1, 2, 3], double)); Write a function, myFilter, that takes in an array and a callback as arguments. The function should mimic the behavior of Array.prototype.filter. function myFilter(arr, callback) { let filtered = []; for (let i = 0; i < arr.length; i++) { let element = arr[i]; if (callback(element, i, arr)) { filtered.push(element); } } return filtered; } Write a function, myEvery, that takes in an array and a callback as arguments. The function should mimic the behavior of Array.prototype.every. function myEvery(arr, callback) { for (let i = 0; i < arr.length; i++) { let element = arr[i]; if (callback(element, i, arr) === false) { return false; } } return true; } Further Examples of the above concepts const createMeowValue = () => { console.log(this.name); let meow = function () { console.log(this); console.log(this.name + ' meows'); } meow = meow.bind(this); return meow; }; const name = 'Fluffy'; const cat = { name: name, age: 12, createMeow: function () { console.log(this.name); let meow = () => { const hello = 'hello'; console.log(this.name + ' meows'); }; let world = ''; if (true) { world = 'world'; } console.log(world); // meow = meow.bind(this); return meow; } }; cat.newKey = function () { const outermostContext = this; const innerFunc = () => { secondContext = this; console.log(secondContext === outermostContext) return function () { innermostContext = this; } }; return innerFunc.bind(outermostContext); }; const meow = cat.createMeow(); // method-style invocation meow(); // function-style invocation console.log('-------') const createMeow = cat.createMeow; const globalMeow = createMeow(); // function-style globalMeow(); // function-style function createSmoothie(ingredient) { const ingredients = [ingredient]; return ingredients; } // console.log(createSmoothie('banana')); // console.log(createSmoothie('apple')); // one parameter only // first argument is a string // return an array // DO NOT USE forEach References: App Academy Open App Academy Open is the first free, online web development course that's meant to get you hired as a developer. Get... open.appacademy.io MDN Web Docs Read more at hacks.mozilla.org Roughly a year ago at Mozilla we started an effort to improve Firefox stability on... developer.mozilla.org Introduction: callbacks To demonstrate the use of callbacks, promises and other abstract concepts, we'll be using some browser methods... javascript.info More content at plainenglish.io By Bryan Guner on May 27, 2021. Canonical link Exported from Medium on July 13, 2021. view raw Array-Call.md hosted with ❤ by GitHub Bash Commands That Save Me Time and Frustration Here's a list of bash commands that stand between me and insanity. Bash Commands That Save Me Time and Frustration Here's a list of bash commands that stand between me and insanity. This article will be accompanied by the following github repository which will contain all the commands listed as well as folders that demonstrate before and after usage! bgoonz/bash-commands-walkthrough to accompany the medium article I am writing. Contribute to bgoonz/bash-commands-walkthrough development by creating an... github.com The readme for this git repo will provide a much more condensed list... whereas this article will break up the commands with explanations... images & links! I will include the code examples as both github gists (for proper syntax highlighting) and as code snippets adjacent to said gists so that they can easily be copied and pasted... or ... if you're like me for instance; and like to use an extension to grab the markdown content of a page... the code will be included rather than just a link to the gist! Here's a Cheatsheet: Getting Started (Advanced Users Skip Section):✔ Check the Current Directory ➡ pwd: On the command line, it's important to know the directory we are currently working on. For that, we can use pwd command. It shows that I'm working on my Desktop directory.✔ Display List of Files ➡ ls: To see the list of files and directories in the current directory use ls command in your CLI. Shows all of my files and directories of my Desktop directory. To show the contents of a directory pass the directory name to the ls command i.e. ls directory_name. Some useful ls command options:- OptionDescriptionls -alist all files including hidden file starting with '.'ls -llist with the long formatls -lalist long format including hidden files✔ Create a Directory ➡ mkdir: We can create a new folder using the mkdir command. To use it type mkdir folder_name. Use ls command to see the directory is created or not. I created a cli-practice directory in my working directory i.e. Desktop directory.✔ Move Between Directories ➡ cd: It's used to change directory or to move other directories. To use it type cd directory_name. Can use pwd command to confirm your directory name. Changed my directory to the cli-practice directory. And the rest of the tutorial I'm gonna work within this directory.✔ Parent Directory ➡ ..: We have seen cd command to change directory but if we want to move back or want to move to the parent directory we can use a special symbol .. after cd command, like cd ..✔ Create Files ➡ touch: We can create an empty file by typing touch file_name. It's going to create a new file in the current directory (the directory you are currently in) with your provided name. I created a hello.txt file in my current working directory. Again you can use ls command to see the file is created or not. Now open your hello.txt file in your text editor and write Hello Everyone! into your hello.txt file and save it.✔ Display the Content of a File ➡ cat: We can display the content of a file using the cat command. To use it type cat file_name. Shows the content of my hello.txt file.✔ Move Files & Directories ➡ mv: To move a file and directory, we use mv command. By typing mv file_to_move destination_directory, you can move a file to the specified directory. By entering mv directory_to_move destination_directory, you can move all the files and directories under that directory. Before using this command, we are going to create two more directories and another txt file in our cli-practice directory. mkdir html css touch bye.txt Yes, we can use multiple directories & files names one after another to create multiple directories & files in one command. Moved my bye.txt file into my css directory and then moved my css directory into my html directory.✔ Rename Files & Directories ➡ mv: mv command can also be used to rename a file and a directory. You can rename a file by typing mv old_file_name new_file_name & also rename a directory by typing mv old_directory_name new_directory_name. Renamed my hello.txt file to the hi.txt file and html directory to the folder directory.✔ Copy Files & Directories ➡ cp: To do this, we use the cp command. You can copy a file by entering cp file_to_copy new_file_name. Copied my hi.txt file content into hello.txt file. For confirmation open your hello.txt file in your text editor. You can also copy a directory by adding the -r option, like cp -r directory_to_copy new_directory_name. The -r option for "recursive" means that it will copy all of the files including the files inside of subfolders. Here I copied all of the files from the folder to folder-copy.✔ Remove Files & Directories ➡ rm: To do this, we use the rm command. To remove a file, you can use the command like rm file_to_remove. Here I removed my hi.txt file. To remove a directory, use the command like rm -r directory_to_remove. I removed my folder-copy directory from my cli-practice directory i.e. current working directory.✔ Clear Screen ➡ clear: Clear command is used to clear the terminal screen.✔ Home Directory ➡ ~: The Home directory is represented by ~. The Home directory refers to the base directory for the user. If we want to move to the Home directory we can use cd ~ command. Or we can only use cd command. MY COMMANDS: 1.) Recursively unzip zip files and then delete the archives when finished: here is a folde r containing the before and after... I had to change folder names slightly due to a limit on the length of file-paths in a github repo. find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; find . -name "*.zip" -type f -print -delete 2.) Install node modules recursively: npm i -g recursive-install npm-recursive-install 3.) Clean up unnecessary files/folders in git repo: find . -empty -type f -print -delete #Remove empty files # ------------------------------------------------------- find . -empty -type d -print -delete #Remove empty folders # ------------------------------------------------------- # This will remove .git folders... .gitmodule files as well as .gitattributes and .gitignore files. find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + # ------------------------------------------------------- # This will remove the filenames you see listed below that just take up space if a repo has been downloaded for use exclusively in your personal file system (in which case the following files just take up space)# Disclaimer... you should not use this command in a repo that you intend to use with your work as it removes files that attribute the work to their original creators! find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "\*CONTRIBUTING.md" \) -exec rm -rf -- {} + In Action: The following output from my bash shell corresponds to the directory: bgoonz/bash-commands-walkthrough Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes... github.com which was created by running the aforementioned commands in in a perfect copy of this directory: bgoonz/DS-ALGO-OFFICIAL Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes... github.com.....below is the terminal output for the following commands: pwd /mnt/c/Users/bryan/Downloads/bash-commands/steps/3-clean-up-fluf/DS-ALGO-OFFICIAL-master After printing the working directory for good measure: find . -empty -type f -print -delete The above command deletes empty files recursively starting from the directory in which it was run:./CONTENT/DS-n-Algos/File-System/file-utilities/node_modules/line-reader/test/data/empty_file.txt ./CONTENT/DS-n-Algos/_Extra-Practice/free-code-camp/nodejs/http-collect.js ./CONTENT/Resources/Comments/node_modules/mime/.npmignore ./markdown/tree2.md ./node_modules/loadashes6/lodash/README.md ./node_modules/loadashes6/lodash/release.md ./node_modules/web-dev-utils/Markdown-Templates/Markdown-Templates-master/filled-out-readme.md |01:33:16|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> The command seen below deletes empty folders recursively starting from the directory in which it was run: find . -empty -type d -print -delete The resulting directories....|01:33:16|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> find . -empty -type d -print -delete ./.git/branches ./.git/objects/info ./.git/refs/tags |01:33:31|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> The command seen below deletes .git folders as well as .gitignore, .gitattributes, .gitmodule files find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + The command seen below deletes most SECURITY, RELEASE, CHANGELOG, LICENSE, CONTRIBUTING, & HISTORY files that take up pointless space in repo's you wish to keep exclusively for your own reference.!!!Use with caution as this command removes the attribution of the work from it's original authors!!!!!!!!Use with caution as this command removes the attribution of the work from it's original authors!!!!!find . ( -name " SECURITY.txt" -o -name " RELEASE.txt" -o -name " CHANGELOG.txt" -o -name " LICENSE.txt" -o -name " CONTRIBUTING.txt" -name " HISTORY.md" -o -name " LICENSE" -o -name " SECURITY.md" -o -name " RELEASE.md" -o -name " CHANGELOG.md" -o -name " LICENSE.md" -o -name " CODE OF CONDUCT.md" -o -name "*CONTRIBUTING.md" ) -exec rm -rf -- {} + 4.) Generate index.html file that links to all other files in working directory:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="index.html" out="basename $out.html" html="index.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<li><a href=\""$1"\">",$1,"&nbsp;</a></li>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html In Action: I will use this copy of my Data Structures Practice Site to demonstrate the result: side-projects-42/DS-Bash-Examples-Deploy Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes... github.com The result is a index.html file that contains a list of links to each file in the directory: here is a link to and photo of the resulting html file: index.html CONTENT/DS-n-Algos/ quirky-meninsky-4181b5.netlify.app 5.) Download all links to a files of a specified extension on a user provided (url) webpage: wget -r -A.pdf https://overapi.com/gitwget --wait=2 --level=inf --limit-rate=20K --recursive --page-requisites --user-agent=Mozilla --no-parent --convert-links --adjust-extension --no-clobber -e robots=off The result is stored in this directory: 6.)Recursively remove lines of text containing the string badFolder from files in the working directory. find . -type f -exec sed -i '/badFolder/d' ./* {} \; # OR find . -name 'result.md' -type f -exec sed -i '/badFolder/d' ./* {} \; As an example I will run this command on a file containing the text: Hacks Blog Read more at hacks.mozilla.org badFolder badFolder Implementing Private Fields for JavaScript When implementing a language feature for JavaScript, an implementer must make decisions about how the language in the specification maps to the implementation. Private fields is an example of where the specification language and implementation reality diverge, at least in SpiderMonkey-- the JavaScript engine which powers Firefox. To understand more, I'll explain what private fields are, a couple of models for thinking about them, and explain why our implementation diverges from the specification language.The post Implementing Private Fields for JavaScript appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, June 8, 2021 by Matthew Gaudet Looking fine with Firefox 89 Firefox 89 has smartened up and brings with it a slimmed-down, slightly more minimalist interface.badFolder Along with this new look, we get some great styling features including a force-colours feature for media queries and better control over how fonts are displayed. The long-awaited top-level await keyword for JavaScript modules is now enabled, as well as the PerformanceEventTiming interface, which is another addition to the performance suite of APIs: 89 really has been working out!The post Looking fine with Firefox 89 appeared first on Mozilla Hacks - the Web developer blog. badFolder Posted Tuesday, June 1, 2021 by Chris Mills badFolder Improving Firefox stability on Linux Roughly a year ago at Mozilla we started an effort to improve Firefox stability on Linux. This effort quickly became an example of good synergies between FOSS projects.The post Improving Firefox stability on Linux appeared first on Mozilla Hacks - the Web developer blog. Posted Wednesday, May 19, 2021 by Gabriele Svelto badFolder Introducing Firefox's new Site Isolation Security Architecture Like any web browser, Firefox loads code from untrusted and potentially hostile websites and runs it on your computer. To protect you against new types of attacks from malicious sites and to meet the security principles of Mozilla, we set out to redesign Firefox on desktop.The post Introducing Firefox's new Site Isolation Security Architecture appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, May 18, 2021 by Anny Gakhokidze Pyodide Spin Out and 0.17 Release We are happy to announce that Pyodide has become an independent and community-driven project. We are also pleased to announce the 0.17 release for Pyodide with many new features and improvements. Pyodide consists of the CPython 3.8 interpreter compiled to WebAssembly which allows Python to run in the browser.The post Pyodide Spin Out and 0.17 Release appeared first on Mozilla Hacks - the Web developer blog. badFolder Posted Thursday, April 22, 2021 by Teon Brooks I modified the command slightly to apply only to files called 'result.md': The result is : Hacks Blog Read more at hacks.mozilla.org When implementing a language feature for JavaScript, an implementer must make decisions about how the language in the specification maps to the implementation. Private fields is an example of where the specification language and implementation reality diverge, at least in SpiderMonkey-- the JavaScript engine which powers Firefox. To understand more, I'll explain what private fields are, a couple of models for thinking about them, and explain why our implementation diverges from the specification language.The post Implementing Private Fields for JavaScript appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, June 8, 2021 by Matthew Gaudet Looking fine with Firefox 89 Posted Tuesday, June 1, 2021 by Chris Mills Improving Firefox stability on Linux Roughly a year ago at Mozilla we started an effort to improve Firefox stability on Linux. This effort quickly became an example of good synergies between FOSS projects.The post Improving Firefox stability on Linux appeared first on Mozilla Hacks - the Web developer blog. Introducing Firefox's new Site Isolation Security Architecture Like any web browser, Firefox loads code from untrusted and potentially hostile websites and runs it on your computer. To protect you against new types of attacks from malicious sites and to meet the security principles of Mozilla, we set out to redesign Firefox on desktop.The post Introducing Firefox's new Site Isolation Security Architecture appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, May 18, 2021 by Anny Gakhokidze Pyodide Spin Out and 0.17 Release Posted Thursday, April 22, 2021 by Teon Brooks the test.txt and result.md files can be found here: bgoonz/bash-commands-walkthrough to accompany the medium article I am writing. Contribute to bgoonz/bash-commands-walkthrough development by creating an... github.com 7.) Execute command recursively: Here I have modified the command I wish to run recursively to account for the fact that the 'find' command already works recursively, by appending the -maxdepth 1 flag... I am essentially removing the recursive action of the find command... That way, if the command affects the more deeply nested folders we know the outer RecurseDirs function we are using to run the find/pandoc line once in every subfolder of the working directory... is working properly! Run in the folder shown to the left... we would expect every .md file to be accompanied by a newly generated html file by the same name. The results of said operation can be found in the following directory In Action:🢃 Below 🢃 The final result is: If you want to run any bash script recursively all you have to do is substitue out line #9 with the command you want to run once in every sub-folder. function RecurseDirs () { oldIFS=$IFS IFS=$'\n' for f in "$@" do #Replace the line below with your own command! #find ./ -iname "*.md" -maxdepth 1 -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; ##################################################### # YOUR CODE BELOW! ##################################################### if [[ -d "${f}" ]]; then cd "${f}" RecurseDirs $(ls -1 ".") cd .. fi done IFS=$oldIFS } RecurseDirs "./" TBC.... Here are some of the other commands I will cover in greater detail... at a later time: 9. Copy any text between
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Bash Commands That Save Me Time and Frustration Bash Commands Bash Commands That Save Me Time and Frustration Here's a list of bash commands that stand between me and insanity. Bash Commands That Save Me Time and Frustration Here's a list of bash commands that stand between me and insanity. https://bryanguner.medium.com/a-list-of-all-of-my-articles-to-link-to-future-posts-1f6f88ebdf5b This article will be accompanied by the following github repository which will contain all the commands listed as well as folders that demonstrate before and after usage! bgoonz/bash-commands-walkthrough to accompany the medium article I am writing. Contribute to bgoonz/bash-commands-walkthrough development by creating an… github.com The readme for this git repo will provide a much more condensed list… whereas this article will break up the commands with explanations… images & links! I will include the code examples as both github gists (for proper syntax highlighting) and as code snippets adjacent to said gists so that they can easily be copied and pasted… or … if you're like me for instance; and like to use an extension to grab the markdown content of a page… the code will be included rather than just a link to the gist! Here's a Cheatsheet: Getting Started (Advanced Users Skip Section):✔ Check the Current Directory ➡ pwd: On the command line, it's important to know the directory we are currently working on. For that, we can use pwd command. It shows that I'm working on my Desktop directory. ✔ Display List of Files ➡ ls: To see the list of files and directories in the current directory use ls command in your CLI. Shows all of my files and directories of my Desktop directory. To show the contents of a directory pass the directory name to the ls command i.e. ls directory_name. Some useful ls command options:- OptionDescriptionls -alist all files including hidden file starting with '.'ls -llist with the long formatls -lalist long format including hidden files✔ Create a Directory ➡ mkdir: We can create a new folder using the mkdir command. To use it type mkdir folder_name. Use `ls` command to see the directory is created or not. I created a cli-practice directory in my working directory i.e. Desktop directory.✔ Move Between Directories ➡ cd: It's used to change directory or to move other directories. To use it type cd directory_name. Can use `pwd` command to confirm your directory name. Changed my directory to the cli-practice directory. And the rest of the tutorial I'm gonna work within this directory.✔ Parent Directory ➡ ..: We have seen cd command to change directory but if we want to move back or want to move to the parent directory we can use a special symbol .. after cd command, like cd ..✔ Create Files ➡ touch: We can create an empty file by typing touch file_name. It's going to create a new file in the current directory (the directory you are currently in) with your provided name. I created a hello.txt file in my current working directory. Again you can use `ls` command to see the file is created or not. Now open your hello.txt file in your text editor and write Hello Everyone! into your hello.txt file and save it.✔ Display the Content of a File ➡ cat: We can display the content of a file using the cat command. To use it type cat file_name. Shows the content of my hello.txt file. ✔ Move Files & Directories ➡ mv: To move a file and directory, we use mv command. By typing mv file_to_move destination_directory, you can move a file to the specified directory. By entering mv directory_to_move destination_directory, you can move all the files and directories under that directory. Before using this command, we are going to create two more directories and another txt file in our cli-practice directory. mkdir html css touch bye.txt Yes, we can use multiple directories & files names one after another to create multiple directories & files in one command. Moved my bye.txt file into my css directory and then moved my css directory into my html directory. ✔ Rename Files & Directories ➡ mv: mv command can also be used to rename a file and a directory. You can rename a file by typing mv old_file_name new_file_name & also rename a directory by typing mv old_directory_name new_directory_name. Renamed my hello.txt file to the hi.txt file and html directory to the folder directory. ✔ Copy Files & Directories ➡ cp: To do this, we use the cp command. You can copy a file by entering cp file_to_copy new_file_name. Copied my hi.txt file content into hello.txt file. For confirmation open your hello.txt file in your text editor. You can also copy a directory by adding the -r option, like cp -r directory_to_copy new_directory_name. The -r option for "recursive" means that it will copy all of the files including the files inside of subfolders. Here I copied all of the files from the folder to folder-copy. ✔ Remove Files & Directories ➡ rm: To do this, we use the rm command. To remove a file, you can use the command like rm file_to_remove. Here I removed my hi.txt file. To remove a directory, use the command like rm -r directory_to_remove. I removed my folder-copy directory from my cli-practice directory i.e. current working directory. ✔ Clear Screen ➡ clear: Clear command is used to clear the terminal screen.✔ Home Directory ➡ ~: The Home directory is represented by ~. The Home directory refers to the base directory for the user. If we want to move to the Home directory we can use cd ~ command. Or we can only use cd command. MY COMMANDS: 1.) Recursively unzip zip files and then delete the archives when finished: here is a folde r containing the before and after… I had to change folder names slightly due to a limit on the length of file-paths in a github repo. find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; find . -name "*.zip" -type f -print -delete 2.) Install node modules recursively: npm i -g recursive-install npm-recursive-install 3.) Clean up unnecessary files/folders in git repo: find . -empty -type f -print -delete #Remove empty files # ------------------------------------------------------- find . -empty -type d -print -delete #Remove empty folders # ------------------------------------------------------- # This will remove .git folders... .gitmodule files as well as .gitattributes and .gitignore files. find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + # ------------------------------------------------------- # This will remove the filenames you see listed below that just take up space if a repo has been downloaded for use exclusively in your personal file system (in which case the following files just take up space)# Disclaimer... you should not use this command in a repo that you intend to use with your work as it removes files that attribute the work to their original creators! find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "\*CONTRIBUTING.md" \) -exec rm -rf -- {} + In Action: The following output from my bash shell corresponds to the directory: bgoonz/bash-commands-walkthrough Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes… github.com which was created by running the aforementioned commands in in a perfect copy of this directory: bgoonz/DS-ALGO-OFFICIAL Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes… github.com…..below is the terminal output for the following commands: pwd /mnt/c/Users/bryan/Downloads/bash-commands/steps/3-clean-up-fluf/DS-ALGO-OFFICIAL-master After printing the working directory for good measure: find . -empty -type f -print -delete The above command deletes empty files recursively starting from the directory in which it was run:./CONTENT/DS-n-Algos/File-System/file-utilities/node_modules/line-reader/test/data/empty_file.txt ./CONTENT/DS-n-Algos/_Extra-Practice/free-code-camp/nodejs/http-collect.js ./CONTENT/Resources/Comments/node_modules/mime/.npmignore ./markdown/tree2.md ./node_modules/loadashes6/lodash/README.md ./node_modules/loadashes6/lodash/release.md ./node_modules/web-dev-utils/Markdown-Templates/Markdown-Templates-master/filled-out-readme.md |01:33:16|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> The command seen below deletes empty folders recursively starting from the directory in which it was run: find . -empty -type d -print -delete The resulting directories….|01:33:16|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> find . -empty -type d -print -delete ./.git/branches ./.git/objects/info ./.git/refs/tags |01:33:31|bryan@LAPTOP-9LGJ3JGS:[DS-ALGO-OFFICIAL-master] DS-ALGO-OFFICIAL-master_exitstatus:0[╗___________o> The command seen below deletes .git folders as well as .gitignore, .gitattributes, .gitmodule files find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + The command seen below deletes most SECURITY, RELEASE, CHANGELOG, LICENSE, CONTRIBUTING, & HISTORY files that take up pointless space in repo's you wish to keep exclusively for your own reference.!!!Use with caution as this command removes the attribution of the work from it's original authors!!!!!!!!Use with caution as this command removes the attribution of the work from it's original authors!!!!! find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + 4.) Generate index.html file that links to all other files in working directory:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="index.html" out="basename $out.html" html="index.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<li><a href=\""$1"\">",$1,"&nbsp;</a></li>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html In Action: I will use this copy of my Data Structures Practice Site to demonstrate the result: side-projects-42/DS-Bash-Examples-Deploy Deployment github-pages Navigation Big O notation is the language we use for talking about how long an algorithm takes… github.com#### The result is a index.html file that contains a list of links to each file in the directory: here is a link to and photo of the resulting html file: index.html CONTENT/DS-n-Algos/ quirky-meninsky-4181b5.netlify.app 5.) Download all links to a files of a specified extension on a user provided (url) webpage: wget -r -A.pdf https://overapi.com/gitwget --wait=2 --level=inf --limit-rate=20K --recursive --page-requisites --user-agent=Mozilla --no-parent --convert-links --adjust-extension --no-clobber -e robots=off The result is stored in this directory: 6.)Recursively remove lines of text containing the string badFolder from files in the working directory. find . -type f -exec sed -i '/badFolder/d' ./* {} \; # OR find . -name 'result.md' -type f -exec sed -i '/badFolder/d' ./* {} \; As an example I will run this command on a file containing the text: Hacks Blog Read more at hacks.mozilla.org badFolder badFolder Implementing Private Fields for JavaScript When implementing a language feature for JavaScript, an implementer must make decisions about how the language in the specification maps to the implementation. Private fields is an example of where the specification language and implementation reality diverge, at least in SpiderMonkey– the JavaScript engine which powers Firefox. To understand more, I'll explain what private fields are, a couple of models for thinking about them, and explain why our implementation diverges from the specification language.The post Implementing Private Fields for JavaScript appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, June 8, 2021 by Matthew Gaudet Looking fine with Firefox 89 Firefox 89 has smartened up and brings with it a slimmed-down, slightly more minimalist interface.badFolder Along with this new look, we get some great styling features including a force-colours feature for media queries and better control over how fonts are displayed. The long-awaited top-level await keyword for JavaScript modules is now enabled, as well as the PerformanceEventTiming interface, which is another addition to the performance suite of APIs: 89 really has been working out!The post Looking fine with Firefox 89 appeared first on Mozilla Hacks - the Web developer blog. badFolder Posted Tuesday, June 1, 2021 by Chris Mills badFolder Improving Firefox stability on Linux Roughly a year ago at Mozilla we started an effort to improve Firefox stability on Linux. This effort quickly became an example of good synergies between FOSS projects.The post Improving Firefox stability on Linux appeared first on Mozilla Hacks - the Web developer blog. Posted Wednesday, May 19, 2021 by Gabriele Svelto badFolder Introducing Firefox's new Site Isolation Security Architecture Like any web browser, Firefox loads code from untrusted and potentially hostile websites and runs it on your computer. To protect you against new types of attacks from malicious sites and to meet the security principles of Mozilla, we set out to redesign Firefox on desktop.The post Introducing Firefox's new Site Isolation Security Architecture appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, May 18, 2021 by Anny Gakhokidze Pyodide Spin Out and 0.17 Release We are happy to announce that Pyodide has become an independent and community-driven project. We are also pleased to announce the 0.17 release for Pyodide with many new features and improvements. Pyodide consists of the CPython 3.8 interpreter compiled to WebAssembly which allows Python to run in the browser.The post Pyodide Spin Out and 0.17 Release appeared first on Mozilla Hacks - the Web developer blog. badFolder Posted Thursday, April 22, 2021 by Teon Brooks I modified the command slightly to apply only to files called 'result.md': The result is : Hacks Blog Read more at hacks.mozilla.org When implementing a language feature for JavaScript, an implementer must make decisions about how the language in the specification maps to the implementation. Private fields is an example of where the specification language and implementation reality diverge, at least in SpiderMonkey– the JavaScript engine which powers Firefox. To understand more, I'll explain what private fields are, a couple of models for thinking about them, and explain why our implementation diverges from the specification language.The post Implementing Private Fields for JavaScript appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, June 8, 2021 by Matthew Gaudet Looking fine with Firefox 89 Posted Tuesday, June 1, 2021 by Chris Mills Improving Firefox stability on Linux Roughly a year ago at Mozilla we started an effort to improve Firefox stability on Linux. This effort quickly became an example of good synergies between FOSS projects.The post Improving Firefox stability on Linux appeared first on Mozilla Hacks - the Web developer blog. Introducing Firefox's new Site Isolation Security Architecture Like any web browser, Firefox loads code from untrusted and potentially hostile websites and runs it on your computer. To protect you against new types of attacks from malicious sites and to meet the security principles of Mozilla, we set out to redesign Firefox on desktop.The post Introducing Firefox's new Site Isolation Security Architecture appeared first on Mozilla Hacks - the Web developer blog. Posted Tuesday, May 18, 2021 by Anny Gakhokidze Pyodide Spin Out and 0.17 Release Posted Thursday, April 22, 2021 by Teon Brooks the test.txt and result.md files can be found here: bgoonz/bash-commands-walkthrough to accompany the medium article I am writing. Contribute to bgoonz/bash-commands-walkthrough development by creating an… github.com 7.) Execute command recursively: Here I have modified the command I wish to run recursively to account for the fact that the 'find' command already works recursively, by appending the -maxdepth 1 flag… I am essentially removing the recursive action of the find command… That way, if the command affects the more deeply nested folders we know the outer RecurseDirs function we are using to run the find/pandoc line once in every subfolder of the working directory… is working properly!**Run in the folder shown to the left… we would expect every .md file to be accompanied by a newly generated html file by the same name.** The results of said operation can be found in the following directory In Action:🢃 Below 🢃 The final result is: If you want to run any bash script recursively all you have to do is substitue out line #9 with the command you want to run once in every sub-folder. function RecurseDirs () { oldIFS=$IFS IFS=$'\n' for f in "$@" do #Replace the line below with your own command! #find ./ -iname "*.md" -maxdepth 1 -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; ##################################################### # YOUR CODE BELOW! ##################################################### if [[ -d "${f}" ]]; then cd "${f}" RecurseDirs $(ls -1 ".") cd .. fi done IFS=$oldIFS } RecurseDirs "./" TBC…. Here are some of the other commands I will cover in greater detail… at a later time: 9. Copy any text between <script> tags in a file called example.html to be inserted into a new file: out.js sed -n -e '/<script>/,/<\/script>/p' example.html >out.js 10. Recursively Delete node_modules folders find . -name 'node_modules' -type d -print -prune -exec rm -rf '{}' + 11. Sanatize file and folder names to remove illegal characters and reserved words. sanitize() { shopt -s extglob; filename=$(basename "$1") directory=$(dirname "$1") filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/') if (test "$filename" != "$filename_clean") then mv -v "$1" "$directory/$filename_clean" fi } export -f sanitize sanitize_dir() { find "$1" -depth -exec bash -c 'sanitize "$0"' {} \; } sanitize_dir '/path/to/somewhere' 12. Start postgresql in terminal sudo -u postgres psql 13. Add closing body and script tags to each html file in working directory. for f in * ; do mv "$f" "$f.html" doneecho "<form> <input type="button" value="Go back!" onclick="history.back()"> </form> </body></html>" | tee -a *.html 14. Batch Download Videos#!/bin/bash link="#insert url here#" #links were a set of strings with just the index of the video as the variable num=3 #first video was numbered 3 - weird. ext=".mp4" while [ $num -le 66 ] do wget $link$num$ext -P ~/Downloads/ num=$(($num+1)) done 15. Change File Extension from '.txt' to .doc for all files in working directory. sudo apt install rename rename 's/\.txt$/.doc/' *.txt 16. Recursivley change any file with extension .js.download to .js find . -name "*.\.js\.download" -exec rename 's/\.js\.download$/.js/' '{}' + 17. Copy folder structure including only files of a specific extension into an ouput Folder find . -name '*.md' | cpio -pdm './../outputFolder' Discover More: Web-Dev-Hub Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of… bgoonz-blog.netlify.app Part 2 of this series: Medium Continued!!!medium.com By Bryan Guner on June 29, 2021. Canonical link Exported from Medium on August 31, 2021. Resources: holy grail 1. Remove spaces from file and folder names and then remove numbers from files and folder names.... Description: need to : sudo apt install rename Notes: Issue when renaming file without numbers collides with existing file name... code: find . -name "* *" -type d | rename 's/ /_/g' find . -name "* *" -type f | rename 's/ /_/g' ```sh find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh find $dir -type d | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh for i in *.html; do mv "$i" "${i%-*}.html"; done for i in *.*; do mv "$i" "${i%-*}.${i##*.}"; done --- ### Description: combine the contents of every file in the contaning directory. >Notes: this includes the contents of the file it's self... ###### code: ```js //APPEND-DIR.js const fs = require('fs'); let cat = require('child_process') .execSync('cat *') .toString('UTF-8'); fs.writeFile('output.md', cat, err => { if (err) throw err; }); 2. Download Website Using Wget: Description: Notes: ==> sudo apt install wget code: wget --limit-rate=200k --no-clobber --convert-links --random-wait -r -p -E -e robots=off -U mozilla https://bootcamp42.gitbook.io/python/ 3. Clean Out Messy Git Repo: Description: recursively removes git related folders as well as internal use files / attributions in addition to empty folders Notes: To clear up clutter in repositories that only get used on your local machine. code: find . -empty -type d -print -delete find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} + find . \( -name "*SECURITY.txt" -o -name "*RELEASE.txt" -o -name "*CHANGELOG.txt" -o -name "*LICENSE.txt" -o -name "*CONTRIBUTING.txt" -name "*HISTORY.md" -o -name "*LICENSE" -o -name "*SECURITY.md" -o -name "*RELEASE.md" -o -name "*CHANGELOG.md" -o -name "*LICENSE.md" -o -name "*CODE_OF_CONDUCT.md" -o -name "*CONTRIBUTING.md" \) -exec rm -rf -- {} + 4. clone all of a user's git repositories Description: clone all of a user or organization's git repositories. Notes: code: Generalized: CNTX={users|orgs}; NAME={username|orgname}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=100" | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone Clone all Git User CNTX={users}; NAME={bgoonz}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone Clone all Git Organization: CNTX={organizations}; NAME={TheAlgorithms}; PAGE=1 curl "https://api.github.com/$CNTX/$NAME/repos?page=$PAGE&per_page=200"?branch=master | grep -e 'git_url*' | cut -d \" -f 4 | xargs -L1 git clone 5. Git Workflow Description: code: git pull git init git add . git commit -m"update" git push -u origin master git init git add . git commit -m"update" git push -u origin main git init git add . git commit -m"update" git push -u origin bryan-guner git init git add . git commit -m"update" git push -u origin gh-pages git init git add . git commit -m"update" git push -u origin preview 6. Recursive Unzip In Place Description: recursively unzips folders and then deletes the zip file by the same name. Notes: code: find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done; find . -name "*.zip" -type f -print -delete 7. git pull keeping local changes: Description: Notes: code: git stash git pull git stash pop 8. Prettier Code Formatter: Description: Notes: code: sudo npm i prettier -g prettier --write . 9. Pandoc Description: Notes: code: find ./ -iname "*.md" -type f -exec sh -c 'pandoc --standalone "${0}" -o "${0%.md}.html"' {} \; find ./ -iname "*.html" -type f -exec sh -c 'pandoc --wrap=none --from html --to markdown_strict "${0}" -o "${0%.html}.md"' {} \; find ./ -iname "*.docx" -type f -exec sh -c 'pandoc "${0}" -o "${0%.docx}.md"' {} \; 10. Gitpod Installs Description: Notes: code: sudo apt install tree sudo apt install pandoc -y sudo apt install rename -y sudo apt install black -y sudo apt install wget -y npm i lebab -g npm i prettier -g npm i npm-recursive-install -g black . prettier --write . npm-recursive-install 11. Repo Utils Package: Description: my standard repo utis package Notes: code: npm i @bgoonz11/repoutils 12. Unix Tree Package Usage: Description: Notes: code: tree -d -I 'node_modules' tree -I 'node_modules' tree -f -I 'node_modules' >TREE.md tree -f -L 2 >README.md tree -f -I 'node_modules' >listing-path.md tree -f -I 'node_modules' -d >TREE.md tree -f >README.md 13. Find & Replace string in file & folder names recursively.. Description: Notes: code: find . -type f -exec rename 's/string1/string2/g' {} + find . -type d -exec rename 's/-master//g' {} + find . -type f -exec rename 's/\.download//g' {} + find . -type d -exec rename 's/-main//g' {} + rename 's/\.js\.download$/.js/' *.js\.download rename 's/\.html\.markdown$/.md/' *.html\.markdown find . -type d -exec rename 's/es6//g' {} + 14. Remove double extensions : Description: Notes: code:#!/bin/bash for file in *.md.md do mv "${file}" "${file%.md}" done #!/bin/bash for file in *.html.html do mv "${file}" "${file%.html}" done #!/bin/bash for file in *.html.png do mv "${file}" "${file%.png}" done for file in *.jpg.jpg do mv "${file}" "${file%.png}" done 15. Truncate folder names down to 12 characters: Description: Notes: code: for d in ./*; do mv $d ${d:0:12}; done 16.Appendir.js Description: combine the contents of every file in the contaning directory. Notes: this includes the contents of the file it's self... code://APPEND-DIR.js const fs = require('fs'); let cat = require('child_process').execSync('cat *').toString('UTF-8'); fs.writeFile('output.md', cat, (err) => { if (err) throw err; }); 17. Replace space in filename with underscore Description: followed by replace '#' with '_' in directory name Notes: Can be re-purposed to find and replace any set of strings in file or folder names. code: find . -name "* *" -type f | rename 's/_//g' find . -name "* *" -type d | rename 's/#/_/g' 18. Filter & delete files by name and extension Description: Notes: code: find . -name '.bin' -type d -prune -exec rm -rf '{}' + find . -name '*.html' -type d -prune -exec rm -rf '{}' + find . -name 'nav-index' -type d -prune -exec rm -rf '{}' + find . -name 'node-gyp' -type d -prune -exec rm -rf '{}' + find . -name 'deleteme.txt' -type f -prune -exec rm -rf '{}' + find . -name 'right.html' -type f -prune -exec rm -rf '{}' + find . -name 'left.html' -type f -prune -exec rm -rf '{}' + 19. Remove lines containing string: Description: Notes: Remove lines not containing '.js' sudo sed -i '/\.js/!d' ./*scrap2.md code: sudo sed -i '/githubusercontent/d' ./*sandbox.md sudo sed -i '/githubusercontent/d' ./*scrap2.md sudo sed -i '/github\.com/d' ./*out.md sudo sed -i '/author/d' ./* 20. Remove duplicate lines from a text file Description: Notes: //...syntax of uniq...// $uniq [OPTION] [INPUT[OUTPUT]] The syntax of this is quite easy to understand. Here, INPUT refers to the input file in which repeated lines need to be filtered out and if INPUT isn't specified then uniq reads from the standard input. OUTPUT refers to the output file in which you can store the filtered output generated by uniq command and as in case of INPUT if OUTPUT isn't specified then uniq writes to the standard output. Now, let's understand the use of this with the help of an example. Suppose you have a text file named kt.txt which contains repeated lines that needs to be omitted. This can simply be done with uniq. code: sudo apt install uniq uniq -u input.txt output.txt 21. Remove lines containing string: Description: Notes: code: sudo sed -i '/githubusercontent/d' ./*sandbox.md sudo sed -i '/githubusercontent/d' ./*scrap2.md sudo sed -i '/github\.com/d' ./*out.md --- title: add_days tags: date,intermediate firstSeen: 2020-10-28T16:19:04+02:00 lastUpdated: 2020-10-28T16:19:04+02:00 --- sudo sed -i '/title:/d' ./*output.md sudo sed -i '/firstSeen/d' ./*output.md sudo sed -i '/lastUpdated/d' ./*output.md sudo sed -i '/tags:/d' ./*output.md sudo sed -i '/badstring/d' ./* sudo sed -i '/stargazers/d' ./repo.txt sudo sed -i '/node_modules/d' ./index.html sudo sed -i '/right\.html/d' ./index.html sudo sed -i '/right\.html/d' ./right.html 22. Zip directory excluding .git and node_modules all the way down (Linux) Description: Notes: code:#!/bin/bash TSTAMP=`date '+%Y%m%d-%H%M%S'` zip -r $1.$TSTAMP.zip $1 -x "**.git/*" -x "**node_modules/*" `shift; echo $@;` printf "\nCreated: $1.$TSTAMP.zip\n" # usage: # - zipdir thedir # - zip thedir -x "**anotherexcludedsubdir/*" (important the double quotes to prevent glob expansion) # if in windows/git-bash, add 'zip' command this way: # https://stackoverflow.com/a/55749636/1482990 23. Delete files containing a certain string: Description: Notes: code: find . | xargs grep -l www.redhat.com | awk '{print "rm "$1}' > doit.sh vi doit.sh // check for murphy and his law source doit.sh 24. Description: Notes: code:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="sitemap.html" out="basename $out.html" html="sitemap.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/bgoonz/GIT-CDN-FILES/mdn-article.css">' echo '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/bgoonz/GIT-CDN-FILES/markdown-to-html-style.css">' echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<li><a href=\""$1"\">",$1,"&nbsp;</a></li>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html 25. Index of Iframes Description: Creates an index.html file that contains all the files in the working directory or any of it's sub folders as iframes instead of anchor tags. Notes: Useful Follow up Code: code:#!/bin/sh # find ./ | grep -i "\.*$" >files find ./ | sed -E -e 's/([^ ]+[ ]+){8}//' | grep -i "\.*$">files listing="files" out="" html="index.html" out="basename $out.html" html="index.html" cmd() { echo ' <!DOCTYPE html>' echo '<html>' echo '<head>' echo ' <meta http-equiv="Content-Type" content="text/html">' echo ' <meta name="Author" content="Bryan Guner">' echo '<link rel="stylesheet" href="./assets/prism.css">' echo ' <link rel="stylesheet" href="./assets/style.css">' echo ' <script async defer src="./assets/prism.js"></script>' echo " <title> directory </title>" echo "" echo '<style>' echo ' a {' echo ' color: black;' echo ' }' echo '' echo ' li {' echo ' border: 1px solid black !important;' echo ' font-size: 20px;' echo ' letter-spacing: 0px;' echo ' font-weight: 700;' echo ' line-height: 16px;' echo ' text-decoration: none !important;' echo ' text-transform: uppercase;' echo ' background: #194ccdaf !important;' echo ' color: black !important;' echo ' border: none;' echo ' cursor: pointer;' echo ' justify-content: center;' echo ' padding: 30px 60px;' echo ' height: 48px;' echo ' text-align: center;' echo ' white-space: normal;' echo ' border-radius: 10px;' echo ' min-width: 45em;' echo ' padding: 1.2em 1em 0;' echo ' box-shadow: 0 0 5px;' echo ' margin: 1em;' echo ' display: grid;' echo ' -webkit-border-radius: 10px;' echo ' -moz-border-radius: 10px;' echo ' -ms-border-radius: 10px;' echo ' -o-border-radius: 10px;' echo ' }' echo ' </style>' echo '</head>' echo '<body>' echo "" # continue with the HTML stuff echo "" echo "" echo "<ul>" awk '{print "<iframe src=\""$1"\">","</iframe>"}' $listing # awk '{print "<li>"}; # {print " <a href=\""$1"\">",$1,"</a></li>&nbsp;"}' \ $listing echo "" echo "</ul>" echo "</body>" echo "</html>" } cmd $listing --sort=extension >>$html 26. Filter Corrupted Git Repo For Troublesome File: Description: Notes: code: git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch assets/_index.html' HEAD 27. OVERWRITE LOCAL CHANGES: Description: Important: If you have any local changes, they will be lost. With or without --hard option, any local commits that haven't been pushed will be lost.[*] If you have any files that are not tracked by Git (e.g. uploaded user content), these files will not be affected. Notes: First, run a fetch to update all origin/ refs to latest: code: git fetch --all # Backup your current branch: git branch backup-master # Then, you have two options: git reset --hard origin/master # OR If you are on some other branch: git reset --hard origin/<branch_name> # Explanation: # git fetch downloads the latest from remote without trying to merge or rebase anything. # Then the git reset resets the master branch to what you just fetched. The --hard option changes all the files in your working tree to match the files in origin/master git fetch --all git reset --hard origin/master 28. Remove Submodules: Description: To remove a submodule you need to: Notes: Delete the relevant section from the .gitmodules file. Stage the .gitmodules changes git add .gitmodules Delete the relevant section from .git/config. Run git rm --cached path to submodule (no trailing slash). Run rm -rf .git/modules/path to submodule (no trailing slash). Commit git commit -m "Removed submodule " Delete the now untracked submodule files rm -rf path to submodule code: git submodule deinit 29. GET GISTS Description: Notes: code: sudo apt install wget wget -q -O - https://api.github.com/users/bgoonz/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget wget -q -O - https://api.github.com/users/amitness/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n3 wget wget -q -O - https://api.github.com/users/drodsou/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget wget -q -O - https://api.github.com/users/thomasmb/gists | grep raw_url | awk -F\" '{print $4}' | xargs -n1 wget 30. Remove Remote OriginL Description: Notes: code: git remote remove origin 31. just clone .git folder: Description: Notes: code: git clone --bare --branch=master --single-branch https://github.com/bgoonz/My-Web-Dev-Archive.git 32. Undo recent pull request: Description: Notes: code: git reset --hard master@{"10 minutes ago"} 33. Lebab Description: ES5 --> ES6 Notes: code:# Safe: lebab --replace ./ --transform arrow lebab --replace ./ --transform arrow-return lebab --replace ./ --transform for-of lebab --replace ./ --transform for-each lebab --replace ./ --transform arg-rest lebab --replace ./ --transform arg-spread lebab --replace ./ --transform obj-method lebab --replace ./ --transform obj-shorthand lebab --replace ./ --transform multi-var # ALL: lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow lebab --replace ./ --transform let lebab --replace ./ --transform arg-spread lebab --replace ./ --transform arg-rest lebab --replace ./ --transform for-each lebab --replace ./ --transform for-of lebab --replace ./ --transform commonjs lebab --replace ./ --transform exponent lebab --replace ./ --transform multi-var lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param lebab --replace ./ --transform includes lebab --replace ./ --transform obj-method lebab --replace ./ --transform class lebab --replace ./ --transform arrow lebab --replace ./ --transform arg-spread lebab --replace ./ --transform arg-rest lebab --replace ./ --transform for-each lebab --replace ./ --transform for-of lebab --replace ./ --transform commonjs lebab --replace ./ --transform exponent lebab --replace ./ --transform multi-var lebab --replace ./ --transform template lebab --replace ./ --transform default-param lebab --replace ./ --transform destruct-param lebab --replace ./ --transform includes 34. Troubleshoot Ubuntu Input/Output Error Description: Open Powershell as Administrator... Notes: code: wsl.exe --shutdown Get-Service LxssManager | Restart-Service 35. Export Medium as Markdown Description: Notes: code: npm i mediumexporter -g mediumexporter https://medium.com/codex/fundamental-data-structures-in-javascript-8f9f709c15b4 >ds.md 36. Delete files in violation of a given size range (100MB for git) Description: Notes: code: find . -size +75M -a -print -a -exec rm -f {} \; find . -size +98M -a -print -a -exec rm -f {} \; 37. download all links of given file type Description: Notes: code: wget -r -A.pdf https://overapi.com/git 38. Kill all node processes Description: Notes: code: killall -s KILL node 39. Remove string from file names recursively Description: In the example below I am using this command to remove the string "-master" from all file names in the working directory and all of it's sub directories. code: find <mydir> -type f -exec sed -i 's/<string1>/<string2>/g' {} + find . -type f -exec rename 's/-master//g' {} + Notes: The same could be done for folder names by changing the -type f flag (for file) to a -type d flag (for directory) find <mydir> -type d -exec sed -i 's/<string1>/<string2>/g' {} + find . -type d -exec rename 's/-master//g' {} + 40. Remove spaces from file and folder names recursively Description: replaces spaces in file and folder names with an _ underscore Notes: need to run sudo apt install rename to use this command code: find . -name "* *" -type d | rename 's/ /_/g' find . -name "* *" -type f | rename 's/ /_/g' 41. Zip Each subdirectories in a given directory into their own zip file Description: Notes: code: for i in */; do zip -r "${i%/}.zip" "$i"; done 42. Description: Notes: code: 43. Description: Notes: code: 44. Description: Notes: code: 45. Description: Notes: code: 46. Description: Notes: code: 47. Description: Notes: code: 48. Description: Notes: code: 49. Description: Notes: code: 50. Description: Notes: code: 51. Description: Notes: code: 52. Description: Notes: code: 53. Description: Notes: code: 54. Description: Notes: code: 55. Description: Notes: code: 56. Description: Notes: code: 57. Description: Notes: code: 58. Description: Notes: code: 59. Description: Notes: code: 60. Description: Notes: code: 61. Description: Notes: code: 62. Description: Notes: code: 63. Description: Notes: code: 64. Description: Notes: code: 65. Description: Notes: code: 66. Description: Notes: code: 67. Description: Notes: code: 68. Description: Notes: code: 69. Description: Notes: code: 70. Description: Notes: code: 71. Description: Notes: code: 72. Description: Notes: code: 73. Description: Notes: code: 74. Description: Notes: code: 75. Description: Notes: code: 76. Description: Notes: code: 77. Description: Notes: code: 78. Description: Notes: code: 79. Description: Notes: code: 80. Description: Notes: code: 81. Description: Notes: code: 82. Description: Notes: code: 83. Description: Notes: code: 84. Description: Notes: code: 85. Description: Notes: code: 86. Description: Notes: code: 87. Description: Notes: code: 88. Description: Notes: code: 89. Description: Notes: code: 90. Description: Notes: code: 91. Unzip PowerShell Description: Notes: code: PARAM ( [string] $ZipFilesPath = "./", [string] $UnzipPath = "./RESULT" ) $Shell = New-Object -com Shell.Application $Location = $Shell.NameSpace($UnzipPath) $ZipFiles = Get-Childitem $ZipFilesPath -Recurse -Include *.ZIP $progress = 1 foreach ($ZipFile in $ZipFiles) { Write-Progress -Activity "Unzipping to $($UnzipPath)" -PercentComplete (($progress / ($ZipFiles.Count + 1)) * 100) -CurrentOperation $ZipFile.FullName -Status "File $($Progress) of $($ZipFiles.Count)" $ZipFolder = $Shell.NameSpace($ZipFile.fullname) $Location.Copyhere($ZipFolder.items(), 1040) # 1040 - No msgboxes to the user - http://msdn.microsoft.com/en-us/library/bb787866%28VS.85%29.aspx $progress++ } 92. return to bash from zsh Description: Notes: code: sudo apt --purge remove zsh 93. Symbolic Link Description: to working directory Notes: code: ln -s "$(pwd)" ~/NameOfLink ln -s "$(pwd)" ~/Downloads 94. auto generate readme Description: rename existing readme to blueprint.md Notes: code: npx @appnest/readme generate 95. Log into postgres: Description: Notes: code: sudo -u postgres psql 96. URL To Subscribe To YouTube Channel Description: Notes: code: https://www.youtube.com/channel/UC1HDa0wWnIKUf-b4yY9JecQ?sub_confirmation=1 97. Embed Repl.it In Medium Post: code: https://repl.it/@bgoonz/Data-Structures-Algos-Codebase?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/node-db1-project?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/interview-prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com https://repl.it/@bgoonz/Database-Prac?lite=true&amp;referrer=https%3A%2F%2Fbryanguner.medium.com 98. Description: Notes: code: find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + find . -name *right.html -type f -exec sed -i 's/target="_parent"//g' {} + 99. Cheat Sheet Description: Notes: code:#!/bin/bash ############################################################################## # SHORTCUTS and HISTORY ############################################################################## CTRL+A # move to beginning of line CTRL+B # moves backward one character CTRL+C # halts the current command CTRL+D # deletes one character backward or logs out of current session, similar to exit CTRL+E # moves to end of line CTRL+F # moves forward one character CTRL+G # aborts the current editing command and ring the terminal bell CTRL+H # deletes one character under cursor (same as DELETE) CTRL+J # same as RETURN CTRL+K # deletes (kill) forward to end of line CTRL+L # clears screen and redisplay the line CTRL+M # same as RETURN CTRL+N # next line in command history CTRL+O # same as RETURN, then displays next line in history file CTRL+P # previous line in command history CTRL+Q # resumes suspended shell output CTRL+R # searches backward CTRL+S # searches forward or suspends shell output CTRL+T # transposes two characters CTRL+U # kills backward from point to the beginning of line CTRL+V # makes the next character typed verbatim CTRL+W # kills the word behind the cursor CTRL+X # lists the possible filename completions of the current word CTRL+Y # retrieves (yank) last item killed CTRL+Z # stops the current command, resume with fg in the foreground or bg in the background ALT+B # moves backward one word ALT+D # deletes next word ALT+F # moves forward one word ALT+H # deletes one character backward ALT+T # transposes two words ALT+. # pastes last word from the last command. Pressing it repeatedly traverses through command history. ALT+U # capitalizes every character from the current cursor position to the end of the word ALT+L # uncapitalizes every character from the current cursor position to the end of the word ALT+C # capitalizes the letter under the cursor. The cursor then moves to the end of the word. ALT+R # reverts any changes to a command you've pulled from your history if you've edited it. ALT+? # list possible completions to what is typed ALT+^ # expand line to most recent match from history CTRL+X then ( # start recording a keyboard macro CTRL+X then ) # finish recording keyboard macro CTRL+X then E # recall last recorded keyboard macro CTRL+X then CTRL+E # invoke text editor (specified by $EDITOR) on current command line then execute resultes as shell commands BACKSPACE # deletes one character backward DELETE # deletes one character under cursor history # shows command line history !! # repeats the last command !<n> # refers to command line 'n' !<string> # refers to command starting with 'string' exit # logs out of current session ############################################################################## # BASH BASICS ############################################################################## env # displays all environment variables echo $SHELL # displays the shell you're using echo $BASH_VERSION # displays bash version bash # if you want to use bash (type exit to go back to your previously opened shell) whereis bash # locates the binary, source and manual-page for a command which bash # finds out which program is executed as 'bash' (default: /bin/bash, can change across environments) clear # clears content on window (hide displayed lines) ############################################################################## # FILE COMMANDS ############################################################################## ls # lists your files in current directory, ls <dir> to print files in a specific directory ls -l # lists your files in 'long format', which contains the exact size of the file, who owns the file and who has the right to look at it, and when it was last modified ls -a # lists all files in 'long format', including hidden files (name beginning with '.') ln -s <filename> <link> # creates symbolic link to file readlink <filename> # shows where a symbolic links points to tree # show directories and subdirectories in easilly readable file tree mc # terminal file explorer (alternative to ncdu) touch <filename> # creates or updates (edit) your file mktemp -t <filename> # make a temp file in /tmp/ which is deleted at next boot (-d to make directory) cat <filename> # prints file raw content (will not be interpreted) any_command > <filename> # '>' is used to perform redirections, it will set any_command's stdout to file instead of "real stdout" (generally /dev/stdout) more <filename> # shows the first part of a file (move with space and type q to quit) head <filename> # outputs the first lines of file (default: 10 lines) tail <filename> # outputs the last lines of file (useful with -f option) (default: 10 lines) vim <filename> # opens a file in VIM (VI iMproved) text editor, will create it if it doesn't exist mv <filename1> <dest> # moves a file to destination, behavior will change based on 'dest' type (dir: file is placed into dir; file: file will replace dest (tip: useful for renaming)) cp <filename1> <dest> # copies a file rm <filename> # removes a file find . -name <name> <type> # searches for a file or a directory in the current directory and all its sub-directories by its name diff <filename1> <filename2> # compares files, and shows where they differ wc <filename> # tells you how many lines, words and characters there are in a file. Use -lwc (lines, word, character) to ouput only 1 of those informations sort <filename> # sorts the contents of a text file line by line in alphabetical order, use -n for numeric sort and -r for reversing order. sort -t -k <filename> # sorts the contents on specific sort key field starting from 1, using the field separator t. rev # reverse string characters (hello becomes olleh) chmod -options <filename> # lets you change the read, write, and execute permissions on your files (more infos: SUID, GUID) gzip <filename> # compresses files using gzip algorithm gunzip <filename> # uncompresses files compressed by gzip gzcat <filename> # lets you look at gzipped file without actually having to gunzip it lpr <filename> # prints the file lpq # checks out the printer queue lprm <jobnumber> # removes something from the printer queue genscript # converts plain text files into postscript for printing and gives you some options for formatting dvips <filename> # prints .dvi files (i.e. files produced by LaTeX) grep <pattern> <filenames> # looks for the string in the files grep -r <pattern> <dir> # search recursively for pattern in directory head -n file_name | tail +n # Print nth line from file. head -y lines.txt | tail +x # want to display all the lines from x to y. This includes the xth and yth lines. ############################################################################## # DIRECTORY COMMANDS ############################################################################## mkdir <dirname> # makes a new directory rmdir <dirname> # remove an empty directory rmdir -rf <dirname> # remove a non-empty directory mv <dir1> <dir2> # rename a directory from <dir1> to <dir2> cd # changes to home cd .. # changes to the parent directory cd <dirname> # changes directory cp -r <dir1> <dir2> # copy <dir1> into <dir2> including sub-directories pwd # tells you where you currently are cd ~ # changes to home. cd - # changes to previous working directory ############################################################################## # SSH, SYSTEM INFO & NETWORK COMMANDS ############################################################################## ssh user@host # connects to host as user ssh -p <port> user@host # connects to host on specified port as user ssh-copy-id user@host # adds your ssh key to host for user to enable a keyed or passwordless login whoami # returns your username passwd # lets you change your password quota -v # shows what your disk quota is date # shows the current date and time cal # shows the month's calendar uptime # shows current uptime w # displays whois online finger <user> # displays information about user uname -a # shows kernel information man <command> # shows the manual for specified command df # shows disk usage du <filename> # shows the disk usage of the files and directories in filename (du -s give only a total) last <yourUsername> # lists your last logins ps -u yourusername # lists your processes kill <PID> # kills the processes with the ID you gave killall <processname> # kill all processes with the name top # displays your currently active processes lsof # lists open files bg # lists stopped or background jobs ; resume a stopped job in the background fg # brings the most recent job in the foreground fg <job> # brings job to the foreground ping <host> # pings host and outputs results whois <domain> # gets whois information for domain dig <domain> # gets DNS information for domain dig -x <host> # reverses lookup host wget <file> # downloads file time <command> # report time consumed by command execution ############################################################################## # VARIABLES ############################################################################## varname=value # defines a variable varname=value command # defines a variable to be in the environment of a particular subprocess echo $varname # checks a variable's value echo $$ # prints process ID of the current shell echo $! # prints process ID of the most recently invoked background job echo $? # displays the exit status of the last command read <varname> # reads a string from the input and assigns it to a variable read -p "prompt" <varname> # same as above but outputs a prompt to ask user for value column -t <filename> # display info in pretty columns (often used with pipe) let <varname> = <equation> # performs mathematical calculation using operators like +, -, *, /, % export VARNAME=value # defines an environment variable (will be available in subprocesses) array[0]=valA # how to define an array array[1]=valB array[2]=valC array=([2]=valC [0]=valA [1]=valB) # another way array=(valA valB valC) # and another ${array[i]} # displays array's value for this index. If no index is supplied, array element 0 is assumed ${#array[i]} # to find out the length of any element in the array ${#array[@]} # to find out how many values there are in the array declare -a # the variables are treated as arrays declare -f # uses function names only declare -F # displays function names without definitions declare -i # the variables are treated as integers declare -r # makes the variables read-only declare -x # marks the variables for export via the environment ${varname:-word} # if varname exists and isn't null, return its value; otherwise return word ${varname:word} # if varname exists and isn't null, return its value; otherwise return word ${varname:=word} # if varname exists and isn't null, return its value; otherwise set it word and then return its value ${varname:?message} # if varname exists and isn't null, return its value; otherwise print varname, followed by message and abort the current command or script ${varname:+word} # if varname exists and isn't null, return word; otherwise return null ${varname:offset:length} # performs substring expansion. It returns the substring of $varname starting at offset and up to length characters ${variable#pattern} # if the pattern matches the beginning of the variable's value, delete the shortest part that matches and return the rest ${variable##pattern} # if the pattern matches the beginning of the variable's value, delete the longest part that matches and return the rest ${variable%pattern} # if the pattern matches the end of the variable's value, delete the shortest part that matches and return the rest ${variable%%pattern} # if the pattern matches the end of the variable's value, delete the longest part that matches and return the rest ${variable/pattern/string} # the longest match to pattern in variable is replaced by string. Only the first match is replaced ${variable//pattern/string} # the longest match to pattern in variable is replaced by string. All matches are replaced ${#varname} # returns the length of the value of the variable as a character string *(patternlist) # matches zero or more occurrences of the given patterns +(patternlist) # matches one or more occurrences of the given patterns ?(patternlist) # matches zero or one occurrence of the given patterns @(patternlist) # matches exactly one of the given patterns !(patternlist) # matches anything except one of the given patterns $(UNIX command) # command substitution: runs the command and returns standard output ############################################################################## # FUNCTIONS ############################################################################## # The function refers to passed arguments by position (as if they were positional parameters), that is, $1, $2, and so forth. # $@ is equal to "$1" "$2"... "$N", where N is the number of positional parameters. $# holds the number of positional parameters. function functname() { shell commands } unset -f functname # deletes a function definition declare -f # displays all defined functions in your login session ############################################################################## # FLOW CONTROLS ############################################################################## statement1 && statement2 # and operator statement1 || statement2 # or operator -a # and operator inside a test conditional expression -o # or operator inside a test conditional expression # STRINGS str1 == str2 # str1 matches str2 str1 != str2 # str1 does not match str2 str1 < str2 # str1 is less than str2 (alphabetically) str1 > str2 # str1 is greater than str2 (alphabetically) str1 \> str2 # str1 is sorted after str2 str1 \< str2 # str1 is sorted before str2 -n str1 # str1 is not null (has length greater than 0) -z str1 # str1 is null (has length 0) # FILES -a file # file exists or its compilation is successful -d file # file exists and is a directory -e file # file exists; same -a -f file # file exists and is a regular file (i.e., not a directory or other special type of file) -r file # you have read permission -s file # file exists and is not empty -w file # your have write permission -x file # you have execute permission on file, or directory search permission if it is a directory -N file # file was modified since it was last read -O file # you own file -G file # file's group ID matches yours (or one of yours, if you are in multiple groups) file1 -nt file2 # file1 is newer than file2 file1 -ot file2 # file1 is older than file2 # NUMBERS -lt # less than -le # less than or equal -eq # equal -ge # greater than or equal -gt # greater than -ne # not equal if condition then statements [elif condition then statements...] [else statements] fi for x in {1..10} do statements done for name [in list] do statements that can use $name done for (( initialisation ; ending condition ; update )) do statements... done case expression in pattern1 ) statements ;; pattern2 ) statements ;; esac select name [in list] do statements that can use $name done while condition; do statements done until condition; do statements done ############################################################################## # COMMAND-LINE PROCESSING CYCLE ############################################################################## # The default order for command lookup is functions, followed by built-ins, with scripts and executables last. # There are three built-ins that you can use to override this order: `command`, `builtin` and `enable`. command # removes alias and function lookup. Only built-ins and commands found in the search path are executed builtin # looks up only built-in commands, ignoring functions and commands found in PATH enable # enables and disables shell built-ins eval # takes arguments and run them through the command-line processing steps all over again ############################################################################## # INPUT/OUTPUT REDIRECTORS ############################################################################## cmd1|cmd2 # pipe; takes standard output of cmd1 as standard input to cmd2 < file # takes standard input from file > file # directs standard output to file >> file # directs standard output to file; append to file if it already exists >|file # forces standard output to file even if noclobber is set n>|file # forces output to file from file descriptor n even if noclobber is set <> file # uses file as both standard input and standard output n<>file # uses file as both input and output for file descriptor n n>file # directs file descriptor n to file n<file # takes file descriptor n from file n>>file # directs file description n to file; append to file if it already exists n>& # duplicates standard output to file descriptor n n<& # duplicates standard input from file descriptor n n>&m # file descriptor n is made to be a copy of the output file descriptor n<&m # file descriptor n is made to be a copy of the input file descriptor &>file # directs standard output and standard error to file <&- # closes the standard input >&- # closes the standard output n>&- # closes the ouput from file descriptor n n<&- # closes the input from file descripor n |tee <file># output command to both terminal and a file (-a to append to file) ############################################################################## # PROCESS HANDLING ############################################################################## # To suspend a job, type CTRL+Z while it is running. You can also suspend a job with CTRL+Y. # This is slightly different from CTRL+Z in that the process is only stopped when it attempts to read input from terminal. # Of course, to interrupt a job, type CTRL+C. myCommand & # runs job in the background and prompts back the shell jobs # lists all jobs (use with -l to see associated PID) fg # brings a background job into the foreground fg %+ # brings most recently invoked background job fg %- # brings second most recently invoked background job fg %N # brings job number N fg %string # brings job whose command begins with string fg %?string # brings job whose command contains string kill -l # returns a list of all signals on the system, by name and number kill PID # terminates process with specified PID kill -s SIGKILL 4500 # sends a signal to force or terminate the process kill -15 913 # Ending PID 913 process with signal 15 (TERM) kill %1 # Where %1 is the number of job as read from 'jobs' command. ps # prints a line of information about the current running login shell and any processes running under it ps -a # selects all processes with a tty except session leaders trap cmd sig1 sig2 # executes a command when a signal is received by the script trap "" sig1 sig2 # ignores that signals trap - sig1 sig2 # resets the action taken when the signal is received to the default disown <PID|JID> # removes the process from the list of jobs wait # waits until all background jobs have finished sleep <number> # wait # of seconds before continuing pv # display progress bar for data handling commands. often used with pipe like |pv yes # give yes response everytime an input is requested from script/process ############################################################################## # TIPS & TRICKS ############################################################################## # set an alias cd; nano .bash_profile > alias gentlenode='ssh admin@gentlenode.com -p 3404' # add your alias in .bash_profile # to quickly go to a specific directory cd; nano .bashrc > shopt -s cdable_vars > export websites="/Users/mac/Documents/websites" source .bashrc cd $websites ############################################################################## # DEBUGGING SHELL PROGRAMS ############################################################################## bash -n scriptname # don't run commands; check for syntax errors only set -o noexec # alternative (set option in script) bash -v scriptname # echo commands before running them set -o verbose # alternative (set option in script) bash -x scriptname # echo commands after command-line processing set -o xtrace # alternative (set option in script) trap 'echo $varname' EXIT # useful when you want to print out the values of variables at the point that your script exits function errtrap { es=$? echo "ERROR line $1: Command exited with status $es." } trap 'errtrap $LINENO' ERR # is run whenever a command in the surrounding script or function exits with non-zero status function dbgtrap { echo "badvar is $badvar" } trap dbgtrap DEBUG # causes the trap code to be executed before every statement in a function or script # ...section of code in which the problem occurs... trap - DEBUG # turn off the DEBUG trap function returntrap { echo "A return occurred" } trap returntrap RETURN # is executed each time a shell function or a script executed with the . or source commands finishes executing ############################################################################## # COLORS AND BACKGROUNDS ############################################################################## # note: \e or \x1B also work instead of \033 # Reset Color_Off='\033[0m' # Text Reset # Regular Colors Black='\033[0;30m' # Black Red='\033[0;31m' # Red Green='\033[0;32m' # Green Yellow='\033[0;33m' # Yellow Blue='\033[0;34m' # Blue Purple='\033[0;35m' # Purple Cyan='\033[0;36m' # Cyan White='\033[0;97m' # White # Additional colors LGrey='\033[0;37m' # Ligth Gray DGrey='\033[0;90m' # Dark Gray LRed='\033[0;91m' # Ligth Red LGreen='\033[0;92m' # Ligth Green LYellow='\033[0;93m'# Ligth Yellow LBlue='\033[0;94m' # Ligth Blue LPurple='\033[0;95m'# Light Purple LCyan='\033[0;96m' # Ligth Cyan # Bold BBlack='\033[1;30m' # Black BRed='\033[1;31m' # Red BGreen='\033[1;32m' # Green BYellow='\033[1;33m'# Yellow BBlue='\033[1;34m' # Blue BPurple='\033[1;35m'# Purple BCyan='\033[1;36m' # Cyan BWhite='\033[1;37m' # White # Underline UBlack='\033[4;30m' # Black URed='\033[4;31m' # Red UGreen='\033[4;32m' # Green UYellow='\033[4;33m'# Yellow UBlue='\033[4;34m' # Blue UPurple='\033[4;35m'# Purple UCyan='\033[4;36m' # Cyan UWhite='\033[4;37m' # White # Background On_Black='\033[40m' # Black On_Red='\033[41m' # Red On_Green='\033[42m' # Green On_Yellow='\033[43m'# Yellow On_Blue='\033[44m' # Blue On_Purple='\033[45m'# Purple On_Cyan='\033[46m' # Cyan On_White='\033[47m' # White # Example of usage echo -e "${Green}This is GREEN text${Color_Off} and normal text" echo -e "${Red}${On_White}This is Red test on White background${Color_Off}" # option -e is mandatory, it enable interpretation of backslash escapes printf "${Red} This is red \n"
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Apendix index This appendix is a non-exhaustive list of new syntactic features and methods that were added to JavaScript in ES6. These features are the most commonly used and most helpful. While this appendix doesn't cover ES6 classes, we go over the basics while learning about components in the book. In addition, this appendix doesn't include descriptions of some larger new features like promises and generators. If you'd like more info on those or on any topic below, we encourage you to reference the Mozilla Developer Network's website (MDN). Prefer const and let over var If you've worked with ES5 JavaScript before, you're likely used to seeing variables declared with var: ar myVariable = 5; Both the const and let statements also declare variables. They were introduced in ES6. Use const in cases where a variable is never re-assigned. Using const makes this clear to whoever is reading your code. It refers to the "constant" state of the variable in the context it is defined within. If the variable will be re-assigned, use let. We encourage the use of const and let instead of var. In addition to the restriction introduced by const, both const and let are block scoped as opposed to function scoped. This scoping can help avoid unexpected bugs. Arrow functions There are three ways to write arrow function bodies. For the examples below, let's say we have an array of city objects: onst cities = [ { name: 'Cairo', pop: 7764700 }, { name: 'Lagos', pop: 8029200 }, ]; If we write an arrow function that spans multiple lines, we must use braces to delimit the function body like this: const formattedPopulations = cities.map((city) => { const popMM = (city.pop / 1000000).toFixed(2); return popMM + ' million'; }); console.log(formattedPopulations); Note that we must also explicitly specify a return for the function. However, if we write a function body that is only a single line (or single expression) we can use parentheses to delimit it: const formattedPopulations2 = cities.map((city) => ( (city.pop / 1000000).toFixed(2) + ' million' )); Notably, we don't use return as it's implied. Furthermore, if your function body is terse you can write it like so: const pops = cities.map(city => city.pop); console.log(pops); The terseness of arrow functions is one of two reasons that we use them. Compare the one-liner above to this: const popsNoArrow = cities.map(function(city) { return city.pop }); Of greater benefit, though, is how arrow functions bind the this object. The traditional JavaScript function declaration syntax ( function () {}) will bind this in anonymous functions to the global object. To illustrate the confusion this causes, consider the following example: unction printSong() { console.log("Oops - The Global Object"); } const jukebox = { songs: [ { title: "Wanna Be Startin' Somethin'", artist: "Michael Jackson", }, { title: "Superstar", artist: "Madonna", }, ], printSong: function (song) { console.log(song.title + " - " + song.artist); }, printSongs: function () { this.songs.forEach(function(song) { this.printSong(song); }); }, } jukebox.printSongs(); The method printSongs() iterates over this.songs with forEach(). In this context, this is bound to the object ( jukebox) as expected. However, the anonymous function passed to forEach() binds its internal this to the global object. As such, this.printSong(song) calls the function declared at the top of the example, not the method on jukebox. JavaScript developers have traditionally used workarounds for this behavior, but arrow functions solve the problem by capturing the this value of the enclosing context. Using an arrow function for printSongs() has the expected result: printSongs: function () { this.songs.forEach((song) => { this.printSong(song); }); }, } jukebox.printSongs(); For this reason, throughout the book we use arrow functions for all anonymous functions. Modules ES6 formally supports modules using the import/ export syntax. Named exports Inside any file, you can use export to specify a variable the module should expose. Here's an example of a file that exports two functions: export const sayHi = () => (console.log('Hi!')); export const sayBye = () => (console.log('Bye!')); const saySomething = () => (console.log('Something!')); Now, anywhere we wanted to use these functions we could use import. We need to specify which functions we want to import. A common way of doing this is using ES6's destructuring assignment syntax to list them out like this: import { sayHi, sayBye } from './greetings'; sayHi(); sayBye(); Importantly, the function that was not exported ( saySomething) is unavailable outside of the module. Also note that we supply a relative path to from, indicating that the ES6 module is a local file as opposed to an npm package. Instead of inserting an export before each variable you'd like to export, you can use this syntax to list off all the exposed variables in one area: const sayHi = () => (console.log('Hi!')); const sayBye = () => (console.log('Bye!')); const saySomething = () => (console.log('Something!')); export { sayHi, sayBye }; We can also specify that we'd like to import all of a module's functionality underneath a given namespace with the import * as <Namespace> syntax: import * as Greetings from './greetings'; Greetings.sayHi(); Greetings.sayBye(); Greetings.saySomething(); Default export The other type of export is a default export. A module can only contain one default export: const sayHi = () => (console.log('Hi!')); const sayBye = () => (console.log('Bye!')); const saySomething = () => (console.log('Something!')); const Greetings = { sayHi, sayBye }; export default Greetings; This is a common pattern for libraries. It means you can easily import the library wholesale without specifying what individual functions you want: import Greetings from './greetings'; Greetings.sayHi(); Greetings.sayBye(); It's not uncommon for a module to use a mix of both named exports and default exports. For instance, with react-dom, you can import ReactDOM (a default export) like this: import ReactDOM from 'react-dom'; ReactDOM.render( ); Or, if you're only going to use the render() function, you can import the named render() function like this: import { render } from 'react-dom'; render( ); To achieve this flexibility, the export implementation for react-dom looks something like this: export const render = (component, target) => { }; const ReactDOM = { render, }; export default ReactDOM; If you want to play around with the module syntax, check out the folder code/webpack/es6-modules. For more reading on ES6 modules, see this article from Mozilla: " ES6 in Depth: Modules". Object.assign() We use Object.assign() often throughout the book. We use it in areas where we want to create a modified version of an existing object. Object.assign() accepts any number of objects as arguments. When the function receives two arguments, it copies the properties of the second object onto the first, like so: onst coffee = { }; const noCream = { cream: false }; const noMilk = { milk: false }; Object.assign(coffee, noCream); It is idiomatic to pass in three arguments to Object.assign(). The first argument is a new JavaScript object, the one that Object.assign() will ultimately return. The second is the object whose properties we'd like to build off of. The last is the changes we'd like to apply: const coffeeWithMilk = Object.assign({}, coffee, { milk: true }); Object.assign() is a handy method for working with "immutable" JavaScript objects. Template literals In ES5 JavaScript, you'd interpolate variables into strings like this: var greeting = 'Hello, ' + user + '! It is ' + degF + ' degrees outside.'; With ES6 template literals, we can create the same string like this: const greeting = `Hello, ${user}! It is ${degF} degrees outside.`; The spread operator (...) In arrays, the ellipsis ... operator will expand the array that follows into the parent array. The spread operator enables us to succinctly construct new arrays as a composite of existing arrays. Here is an example: onst a = [ 1, 2, 3 ]; const b = [ 4, 5, 6 ]; const c = [ ...a, ...b, 7, 8, 9 ]; console.log(c); Notice how this is different than if we wrote: const d = [ a, b, 7, 8, 9 ]; console.log(d); Enhanced object literals In ES5, all objects were required to have explicit key and value declarations: const explicit = { getState: getState, dispatch: dispatch, }; In ES6, you can use this terser syntax whenever the property name and variable name are the same: const implicit = { getState, dispatch, }; Lots of open source libraries use this syntax, so it's good to be familiar with it. But whether you use it in your own code is a matter of stylistic preference. Default arguments With ES6, you can specify a default value for an argument in the case that it is undefined when the function is called. This: unction divide(a, b) { const divisor = typeof b === 'undefined' ? 1 : b; return a / divisor; } Can be written as this: function divide(a, b = 1) { return a / b; } In both cases, using the function looks like this: divide(14, 2); divide(14, undefined); divide(14); Whenever the argument b in the example above is undefined, the default argument is used. Note that null will not use the default argument: divide(14, null); Destructuring assignments For arrays In ES5, extracting and assigning multiple elements from an array looked like this: ar fruits = [ 'apples', 'bananas', 'oranges' ]; var fruit1 = fruits[0]; var fruit2 = fruits[1]; In ES6, we can use the destructuring syntax to accomplish the same task like this: const [ veg1, veg2 ] = [ 'asparagus', 'broccoli', 'onion' ]; console.log(veg1); console.log(veg2); The variables in the array on the left are "matched" and assigned to the corresponding elements in the array on the right. Note that 'onion' is ignored and has no variable bound to it. For objects We can do something similar for extracting object properties into variables: const smoothie = { fats: [ 'avocado', 'peanut butter', 'greek yogurt' ], liquids: [ 'almond milk' ], greens: [ 'spinach' ], fruits: [ 'blueberry', 'banana' ], }; const { liquids, fruits } = smoothie; console.log(liquids); console.log(fruits); Parameter context matching We can use these same principles to bind arguments inside a function to properties of an object supplied as an argument: const containsSpinach = ({ greens }) => { if (greens.find(g => g === 'spinach')) { return true; } else { return false; } }; containsSpinach(smoothie); We do this often with functional React components: const IngredientList = ({ ingredients, onClick }) => ( <ul className='IngredientList'> { ingredients.map(i => ( <li key={i.id} onClick={() => onClick(i.id)} className='item' > {i.name} </li> )) } </ul> ) Here, we use destructuring to extract the props into variables ( ingredients and onClick) that we then use inside the component's function body.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Trouble Shooting Trouble Shooting Log
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    RECENT PROJECTS Potluck Planner Meditation App Web Audio DAW React & Shopify Ecommerce Site (Norwex) Bgoonz Bookmarks Goal Tracker
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    History API History Api The DOM Window object provides access to the browser's session history (not to be confused for WebExtensions history) through the history object. It exposes useful methods and properties that let you navigate back and forth through the user's history, and manipulate the contents of the history stack. Concepts and usage Moving backward and forward through the user's history is done using the back(), forward(), and go() methods. Moving forward and backward To move backward through history: This acts exactly as if the user clicked on the Back button in their browser toolbar. Similarly, you can move forward (as if the user clicked the Forward button), like this: Moving to a specific point in history You can use the go() method to load a specific page from session history, identified by its relative position to the current page. (The current page's relative position is 0.) To move back one page (the equivalent of calling back()): To move forward a page, just like calling forward(): Similarly, you can move forward 2 pages by passing 2, and so forth. Another use for the go() method is to refresh the current page by either passing 0, or by invoking it without an argument: You can determine the number of pages in the history stack by looking at the value of the length property: Interfaces Allows manipulation of the browser session history (that is, the pages visited in the tab or frame that the current page is loaded in). Examples The following example assigns a listener to the onpopstate property. And then illustrates some of the methods of the history object to add, replace, and move within the browser history for the current tab. Working with the History API HTML5 introduced the pushState() and replaceState() methods for add and modifying history entries, respectively. These methods work in conjunction with the onpopstate event. Adding and modifying history entries Using pushState() changes the referrer that gets used in the HTTP header for XMLHttpRequest objects created after you change the state. The referrer will be the URL of the document whose window is this at the time of creation of the XMLHttpRequest object. Example of pushState() method Suppose https://mozilla.org/foo.html executes the following JavaScript: This will cause the URL bar to display https://mozilla.org/bar.html, but won't cause the browser to load bar.html or even check that bar.html exists. Suppose now that the user navigates to https://google.com, then clicks the Back button. At this point, the URL bar will display https://mozilla.org/bar.html and history.state will contain the stateObj. The popstate event won't be fired because the page has been reloaded. The page itself will look like bar.html. If the user clicks Back once again, the URL will change to https://mozilla.org/foo.html, and the document will get a popstate event, this time with a null state object. Here too, going back doesn't change the document's contents from what they were in the previous step, although the document might update its contents manually upon receiving the popstate event. The pushState() method pushState() takes three parameters: a state object; a title (currently ignored); and (optionally), a URL. Let's examine each of these three parameters in more detail. The state object is a JavaScript object which is associated with the new history entry created by pushState(). Whenever the user navigates to the new state, a popstate event is fired, and the state property of the event contains a copy of the history entry's state object. The state object can be anything that can be serialized. Because Firefox saves state objects to the user's disk so they can be restored after the user restarts the browser, we impose a size limit of 640k characters on the serialized representation of a state object. If you pass a state object whose serialized representation is larger than this to pushState(), the method will throw an exception. If you need more space than this, you're encouraged to use sessionStorage and/or localStorage. All browsers but Safari currently ignore this parameter, although they may use it in the future. Passing the empty string here should be safe against future changes to the method. Alternatively, you could pass a short title for the state to which you're moving. The new history entry's URL is given by this parameter. Note that the browser won't attempt to load this URL after a call to pushState(), but it might attempt to load the URL later, for instance after the user restarts the browser. The new URL does not need to be absolute; if it's relative, it's resolved relative to the current URL. The new URL must be of the same origin as the current URL; otherwise, pushState() will throw an exception. This parameter is optional; if it isn't specified, it's set to the document's current URL. Note: In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) through Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed object is serialized using JSON. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the object is serialized using the structured clone algorithm. This allows a wider variety of objects to be safely passed. In a sense, calling pushState() is similar to setting window.location = "#foo", in that both will also create and activate another history entry associated with the current document. But pushState() has a few advantages: The new URL can be any URL in the same origin as the current URL. In contrast, setting window.location keeps you at the same document only if you modify only the hash. You don't have to change the URL if you don't want to. In contrast, setting window.location = "#foo"; creates a new history entry only if the current hash isn't #foo. You can associate arbitrary data with your new history entry. With the hash-based approach, you need to encode all of the relevant data into a short string. If title is subsequently used by browsers, this data can be utilized (independent of, say, the hash). Note that pushState() never causes a hashchange event to be fired, even if the new URL differs from the old URL only in its hash. In other documents, it creates an element with a null namespace URI. The replaceState() method history.replaceState() operates exactly like history.pushState(), except that replaceState() modifies the current history entry instead of creating a new one. Note that this doesn't prevent the creation of a new entry in the global browser history. replaceState() is particularly useful when you want to update the state object or URL of the current history entry in response to some user action. Note: In Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1) through Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2), the passed object is serialized using JSON. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the object is serialized using the structured clone algorithm. This allows a wider variety of objects to be safely passed. Example of replaceState() method Suppose https://mozilla.org/foo.html executes the following JavaScript: The explanation of these two lines above can be found at the above section Example of pushState() method section. Next, suppose https://mozilla.org/bar.html executes the following JavaScript: This will cause the URL bar to display https://mozilla.org/bar2.html, but won't cause the browser to load bar2.html or even check that bar2.html exists. Suppose now that the user navigates to https://www.microsoft.com, then clicks the Back button. At this point, the URL bar will display https://mozilla.org/bar2.html. If the user now clicks Back again, the URL bar will display https://mozilla.org/foo.html, and totally bypass bar.html. The popstate event A popstate event is dispatched to the window every time the active history entry changes. If the history entry being activated was created by a call to pushState or affected by a call to replaceState, the popstate event's state property contains a copy of the history entry's state object. See WindowEventHandlers.onpopstate for sample usage. Reading the current state When your page loads, it might have a non-null state object. This can happen, for example, if the page sets a state object (using pushState() or replaceState()) and then the user restarts their browser. When the page reloads, the page will receive an onload event, but no popstate event. However, if you read the history.state property, you'll get back the state object you would have gotten if a popstate had fired. You can read the state of the current history entry without waiting for a popstate event using the history.state property like this: See also History API Ajax navigation example window.history Window.historyCopy to Clipboard The Window.history read-only property returns a reference to the History object, which provides an interface for manipulating the browser session history (pages visited in the tab or frame that the current page is loaded in). See Manipulating the browser history for examples and details. In particular, that article explains security features of the pushState() and replaceState() methods that you should be aware of before using them. Example Notes For top-level pages you can see the list of pages in the session history, accessible via the History object, in the browser's dropdowns next to the back and forward buttons. For security reasons the History object doesn't allow the non-privileged code to access the URLs of other pages in the session history, but it does allow it to navigate the session history. There is no way to clear the session history or to disable the back/forward navigation from unprivileged code. The closest available solution is the location.replace() method, which replaces the current item of the session history with the provided URL.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Queries and Mutations (Gatsby) Querying Data in Components using StaticQuery TABLE OF CONTENTS How to use StaticQuery in components Basic example useStaticQuery Typechecking How StaticQuery differs from page query Gatsby v2 introduces StaticQuery, a new API that allows components to retrieve data via a GraphQL query. In this guide, you'll see an example using StaticQuery, and learn about the difference between a StaticQuery and a page query. How to use StaticQuery in components Video hosted on egghead.io. Basic example Here is an example of a Header component using StaticQuery: src/components/header.js Copysrc/components/header.js: copy code to clipboard` import React from "react" import { StaticQuery, graphql } from "gatsby" export default function Header() { return (<StaticQuery query={graphql` query HeadingQuery { site { siteMetadata { title}}}`} render={data => ({data.site.siteMetadata.title})}/>)}` By using StaticQuery, you can colocate a component with its data. It is no longer required to, say, pass data down from Layout to Header. useStaticQuery There's also a React hooks version of StaticQuery: check out the documentation on useStaticQuery Typechecking With the above pattern, you lose the ability to typecheck with PropTypes. To regain typechecking while achieving the same result, you can change the component to: src/components/header.js Copysrc/components/header.js: copy code to clipboard` import React from "react" import { StaticQuery, graphql } from "gatsby" import PropTypes from "prop-types" const Header = ({ data }) => ({data.site.siteMetadata.title}) export default function MyHeader(props) { return (<StaticQuery query={graphql` query { site { siteMetadata { title}}}`} render={data => <Header data={data} {...props} />}/>)} Header.propTypes = { data: PropTypes.shape({ site: PropTypes.shape({ siteMetadata: PropTypes.shape({ title: PropTypes.string.isRequired,}).isRequired,}).isRequired,}).isRequired,}` How StaticQuery differs from page query StaticQuery can do most of the things that page query can, including fragments. The main differences are: page queries can accept variables (via pageContext) but can only be added to page components StaticQuery does not accept variables (hence the name "static"), but can be used in any component, including pages StaticQuery does not work with raw React.createElement calls; please use JSX, e.g. <StaticQuery /> GraphQL Queries and Mutations On this page, you'll learn in detail about how to query a GraphQL server. Fields At its simplest, GraphQL is about asking for specific fields on objects. Let's start by looking at a very simple query and the result we get when we run it:{ hero { name}}{"data": {"hero": {"name": "R2-D2"}}} You can see immediately that the query has exactly the same shape as the result. This is essential to GraphQL, because you always get back what you expect, and the server knows exactly what fields the client is asking for. The field name returns a String type, in this case the name of the main hero of Star Wars, "R2-D2". Oh, one more thing - the query above is interactive. That means you can change it as you like and see the new result. Try adding an appearsIn field to the hero object in the query, and see the new result. In the previous example, we just asked for the name of our hero which returned a String, but fields can also refer to Objects. In that case, you can make a sub-selection of fields for that object. GraphQL queries can traverse related objects and their fields, letting clients fetch lots of related data in one request, instead of making several roundtrips as one would need in a classic REST architecture.{ hero { name Queries can have comments! friends { name}}}{"data": {"hero": {"name": "R2-D2","friends": [{"name": "Luke Skywalker"},{"name": "Han Solo"},{"name": "Leia Organa"}]}}} Note that in this example, the friends field returns an array of items. GraphQL queries look the same for both single items or lists of items, however we know which one to expect based on what is indicated in the schema. Arguments If the only thing we could do was traverse objects and their fields, GraphQL would already be a very useful language for data fetching. But when you add the ability to pass arguments to fields, things get much more interesting.{ human(id: "1000") { name height}}{"data": {"human": {"name": "Luke Skywalker","height": 1.72}}} In a system like REST, you can only pass a single set of arguments - the query parameters and URL segments in your request. But in GraphQL, every field and nested object can get its own set of arguments, making GraphQL a complete replacement for making multiple API fetches. You can even pass arguments into scalar fields, to implement data transformations once on the server, instead of on every client separately.{ human(id: "1000") { name height(unit: FOOT)}}{"data": {"human": {"name": "Luke Skywalker","height": 5.6430448}}} Arguments can be of many different types. In the above example, we have used an Enumeration type, which represents one of a finite set of options (in this case, units of length, either METER or FOOT). GraphQL comes with a default set of types, but a GraphQL server can also declare its own custom types, as long as they can be serialized into your transport format. Read more about the GraphQL type system here. Aliases If you have a sharp eye, you may have noticed that, since the result object fields match the name of the field in the query but don't include arguments, you can't directly query for the same field with different arguments. That's why you need aliases - they let you rename the result of a field to anything you want.{ empireHero: hero(episode: EMPIRE) { name} jediHero: hero(episode: JEDI) { name}}{"data": {"empireHero": {"name": "Luke Skywalker"},"jediHero": {"name": "R2-D2"}}} In the above example, the two hero fields would have conflicted, but since we can alias them to different names, we can get both results in one request. Fragments Let's say we had a relatively complicated page in our app, which lets us look at two heroes side by side, along with their friends. You can imagine that such a query could quickly get complicated, because we would need to repeat the fields at least once - one for each side of the comparison. That's why GraphQL includes reusable units called fragments. Fragments let you construct sets of fields, and then include them in queries where you need to. Here's an example of how you could solve the above situation using fragments:{ leftComparison: hero(episode: EMPIRE) {...comparisonFields} rightComparison: hero(episode: JEDI) {...comparisonFields}}​ fragment comparisonFields on Character { name appearsIn friends { name}}{"data": {"leftComparison": {"name": "Luke Skywalker","appearsIn": ["NEWHOPE","EMPIRE","JEDI"],"friends": [{"name": "Han Solo"},{"name": "Leia Organa"},{"name": "C-3PO"},{"name": "R2-D2"}]},"rightComparison": {"name": "R2-D2","appearsIn": ["NEWHOPE","EMPIRE","JEDI"],"friends": [{"name": "Luke Skywalker"},{"name": "Han Solo"},{"name": "Leia Organa"}]}}} You can see how the above query would be pretty repetitive if the fields were repeated. The concept of fragments is frequently used to split complicated application data requirements into smaller chunks, especially when you need to combine lots of UI components with different fragments into one initial data fetch. Using variables inside fragments It is possible for fragments to access variables declared in the query or mutation. See variables. query HeroComparison($first: Int = 3) { leftComparison: hero(episode: EMPIRE) {...comparisonFields} rightComparison: hero(episode: JEDI) {...comparisonFields}}​ fragment comparisonFields on Character { name friendsConnection(first: $first) { totalCount edges { node { name}}}}​{"errors": [{"message": "Buffer is not defined","locations": [{"line": 12,"column": 3}],"path": ["leftComparison","friendsConnection"]},{"message": "Buffer is not defined","locations": [{"line": 12,"column": 3}],"path": ["rightComparison","friendsConnection"]}],"data": {"leftComparison": null,"rightComparison": null}} Operation name Up until now, we have been using a shorthand syntax where we omit both the query keyword and the query name, but in production apps it's useful to use these to make our code less ambiguous. Here's an example that includes the keyword query as operation type and HeroNameAndFriends as operation name : query HeroNameAndFriends { hero { name friends { name}}}{"data": {"hero": {"name": "R2-D2","friends": [{"name": "Luke Skywalker"},{"name": "Han Solo"},{"name": "Leia Organa"}]}}} The operation type is either query, mutation, or subscription and describes what type of operation you're intending to do. The operation type is required unless you're using the query shorthand syntax, in which case you can't supply a name or variable definitions for your operation. The operation name is a meaningful and explicit name for your operation. It is only required in multi-operation documents, but its use is encouraged because it is very helpful for debugging and server-side logging. When something goes wrong (you see errors either in your network logs, or in the logs of your GraphQL server) it is easier to identify a query in your codebase by name instead of trying to decipher the contents. Think of this just like a function name in your favorite programming language. For example, in JavaScript we can easily work only with anonymous functions, but when we give a function a name, it's easier to track it down, debug our code, and log when it's called. In the same way, GraphQL query and mutation names, along with fragment names, can be a useful debugging tool on the server side to identify different GraphQL requests. Variables So far, we have been writing all of our arguments inside the query string. But in most applications, the arguments to fields will be dynamic: For example, there might be a dropdown that lets you select which Star Wars episode you are interested in, or a search field, or a set of filters. It wouldn't be a good idea to pass these dynamic arguments directly in the query string, because then our client-side code would need to dynamically manipulate the query string at runtime, and serialize it into a GraphQL-specific format. Instead, GraphQL has a first-class way to factor dynamic values out of the query, and pass them as a separate dictionary. These values are called variables. When we start working with variables, we need to do three things: Replace the static value in the query with $variableName Declare $variableName as one of the variables accepted by the query Pass variableName: value in the separate, transport-specific (usually JSON) variables dictionary Here's what it looks like all together: query HeroNameAndFriends($episode: Episode) { hero(episode: $episode) { name friends { name}}}{"episode": "JEDI"}{"data": {"hero": {"name": "R2-D2","friends": [{"name": "Luke Skywalker"},{"name": "Han Solo"},{"name": "Leia Organa"}]}}} Now, in our client code, we can simply pass a different variable rather than needing to construct an entirely new query. This is also in general a good practice for denoting which arguments in our query are expected to be dynamic - we should never be doing string interpolation to construct queries from user-supplied values. Variable definitions The variable definitions are the part that looks like ($episode: Episode) in the query above. It works just like the argument definitions for a function in a typed language. It lists all of the variables, prefixed by $, followed by their type, in this case Episode. All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server. Learn more about input object types on the Schema page. Variable definitions can be optional or required. In the case above, since there isn't an ! next to the Episode type, it's optional. But if the field you are passing the variable into requires a non-null argument, then the variable has to be required as well. To learn more about the syntax for these variable definitions, it's useful to learn the GraphQL schema language. The schema language is explained in detail on the Schema page. Default variables Default values can also be assigned to the variables in the query by adding the default value after the type declaration. query HeroNameAndFriends($episode: Episode = JEDI) { hero(episode: $episode) { name friends { name}}} When default values are provided for all variables, you can call the query without passing any variables. If any variables are passed as part of the variables dictionary, they will override the defaults. Directives We discussed above how variables enable us to avoid doing manual string interpolation to construct dynamic queries. Passing variables in arguments solves a pretty big class of these problems, but we might also need a way to dynamically change the structure and shape of our queries using variables. For example, we can imagine a UI component that has a summarized and detailed view, where one includes more fields than the other. Let's construct a query for such a component: query Hero($episode: Episode, $withFriends: Boolean!) { hero(episode: $episode) { name friends @include(if: $withFriends) { name}}}{"episode": "JEDI","withFriends": false}{"data": {"hero": {"name": "R2-D2"}}} Try editing the variables above to instead pass true for withFriends, and see how the result changes. We needed to use a new feature in GraphQL called a directive. A directive can be attached to a field or fragment inclusion, and can affect execution of the query in any way the server desires. The core GraphQL specification includes exactly two directives, which must be supported by any spec-compliant GraphQL server implementation:@include(if: Boolean) Only include this field in the result if the argument is true.@skip(if: Boolean) Skip this field if the argument is true. Directives can be useful to get out of situations where you otherwise would need to do string manipulation to add and remove fields in your query. Server implementations may also add experimental features by defining completely new directives. Mutations Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request might end up causing some side-effects on the server, but by convention it's suggested that one doesn't use GET requests to modify data. GraphQL is similar - technically any query could be implemented to cause a data write. However, it's useful to establish a convention that any operations that cause writes should be sent explicitly via a mutation. Just like in queries, if the mutation field returns an object type, you can ask for nested fields. This can be useful for fetching the new state of an object after an update. Let's look at a simple example mutation: mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) { createReview(episode: $ep, review: $review) { stars commentary}}{"ep": "JEDI","review": {"stars": 5,"commentary": "This is a great movie!"}}{"data": {"createReview": {"stars": 5,"commentary": "This is a great movie!"}}} Note how createReview field returns the stars and commentary fields of the newly created review. This is especially useful when mutating existing data, for example, when incrementing a field, since we can mutate and query the new value of the field with one request. You might also notice that, in this example, the review variable we passed in is not a scalar. It's an input object type, a special kind of object type that can be passed in as an argument. Learn more about input types on the Schema page. Multiple fields in mutations A mutation can contain multiple fields, just like a query. There's one important distinction between queries and mutations, other than the name: While query fields are executed in parallel, mutation fields run in series, one after the other. This means that if we send two incrementCredits mutations in one request, the first is guaranteed to finish before the second begins, ensuring that we don't end up with a race condition with ourselves. Inline Fragments Like many other type systems, GraphQL schemas include the ability to define interfaces and union types. Learn about them in the schema guide. If you are querying a field that returns an interface or a union type, you will need to use inline fragments to access data on the underlying concrete type. It's easiest to see with an example: query HeroForEpisode($ep: Episode!) { hero(episode: $ep) { name... on Droid { primaryFunction}... on Human { height}}}{"ep": "JEDI"}{"data": {"hero": {"name": "R2-D2","primaryFunction": "Astromech"}}} In this query, the hero field returns the type Character, which might be either a Human or a Droid depending on the episode argument. In the direct selection, you can only ask for fields that exist on the Character interface, such as name. To ask for a field on the concrete type, you need to use an inline fragment with a type condition. Because the first fragment is labeled as ... on Droid, the primaryFunction field will only be executed if the Character returned from hero is of the Droid type. Similarly for the height field for the Human type. Named fragments can also be used in the same way, since a named fragment always has a type attached. Meta fields Given that there are some situations where you don't know what type you'll get back from the GraphQL service, you need some way to determine how to handle that data on the client. GraphQL allows you to request __typename, a meta field, at any point in a query to get the name of the object type at that point.{ search(text: "an") { __typename... on Human { name}... on Droid { name}... on Starship { name}}}{"data": {"search": [{"__typename": "Human","name": "Han Solo"},{"__typename": "Human","name": "Leia Organa"},{"__typename": "Starship","name": "TIE Advanced x1"}]}} In the above query, search returns a union type that can be one of three options. It would be impossible to tell apart the different types from the client without the __typename field. GraphQL services provide a few meta fields, the rest of which are used to expose the Introspection system.****
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Archive Archives: Text Tools Ternary Converter ******************** 1 2 3 4 5 leonardomso/33-js-concepts This repository was created with the intention of helping developers master their concepts in JavaScript. It is not a… github.com Call stack - MDN Web Docs Glossary: Definitions of Web-related terms MDN A call stack is a mechanism for an interpreter (like the JavaScript interpreter in a web browser) to keep track of its… developer.mozilla.org Understanding Javascript Function Executions — Call Stack, Event Loop , Tasks & more Web developers or Front end engineers, as that's what we like to be called, nowadays do everything right from acting as… medium.com Understanding the JavaScript call stack The JavaScript engine (which is found in a hosting environment like the browser), is a single-threaded interpreter… medium.freecodecamp.org Javascript: What Is The Execution Context? What Is The Call Stack? What is the Execution Context in Javascript? I bet you don't know the answer. What are the most basic components of a… web.archive.org Understanding Execution Context and Execution Stack in Javascript Understanding execution context and stack to become a better Javascript developer. blog.bitsrc.io JavaScript data types and data structures - JavaScript MDN Programming languages all have built-in data structures, but these often differ from one language to another. This… developer.mozilla.org How numbers are encoded in JavaScript Edit description 2ality.com Here is what you need to know about JavaScript's Number type Why 0.1+0.2 IS NOT equal to 0.3 and 9007199254740992 IS equal to 9007199254740993 medium.com What Every JavaScript Developer Should Know About Floating Point Numbers After I gave my talk on JavaScript (really, I was there trying to shamelessly plug my book - Underhanded JavaScript and… blog.chewxy.com The Secret Life of JavaScript Primitives You may not know it but, in JavaScript, whenever you interact with string, number or boolean primitives you enter a… javascriptweblog.wordpress.com JavaScript Reference and Copy Variables Hacker Noon Each programming language has its own peculiarities (and JavaScript has a lot), and today I'm going to talk about… hackernoon.com JavaScript Primitive vs. Reference Values Summary: in this tutorial, you will learn the differences between primitive and reference values. In JavaScript, a… www.javascripttutorial.net JavaScript by reference vs. by value I'm looking for some good comprehensive reading material on when JavaScript passes something by value and when by… stackoverflow.com JavaScript Interview Prep: Primitive vs. Reference Types original article In a JavaScript interview, they might ask if you understand the difference between primitive and… dev.to What you need to know about Javascript's Implicit Coercion Javascript's implicit coercion simply refers to Javascript attempting to coerce an unexpected value type to the… dev.to Javascript Coercion Explained Along with some practical examples hackernoon.com What exactly is Type Coercion in Javascript? Let's start with a short intro to type systems which I think will help you understand the general idea of type… stackoverflow.com https://thedevs.network/*Weak dynamic typing is arguably one of those things everybody likes to pick at about JavaScript. For an elegant dynamic…*thedevs.network getify/You-Dont-Know-JS A book series on JavaScript. @YDKJS on twitter. Contribute to getify/You-Dont-Know-JS development by creating an… github.com JavaScript — Double Equals vs. Triple Equals Learn equality in JavaScript in 3 minutes codeburst.io Why Use the Triple-Equals Operator in JavaScript? - Impressive Webs“Determining whether two variables are equivalent is one of the most important operations in programming.” That's… www.impressivewebs.com What is the difference between == and === in JavaScript?_On the surface == and === appear to be functionally the same, so why bother typing an extra character? In this video…_www.oreilly.com Why javascript's typeof always return “object”? To add in with the others, typeof returns both objects and primitives. There are 5 primitive types in javascript… stackoverflow.com Checking Types in Javascript Have you ever wondered: what is the correct way to check if a Javascript variable is an Array? Do a Google search and… tobyho.com How to better check data types in javascript - Webbjocke To check what data type something has in javascript is not always the easiest. The language itself provides an operator… webbjocke.com A JavaScript Fundamentals Cheat Sheet: Scope, Context, and “this” Scope Scope refers to where a variable can be accessed within a program. Some variables can be accessed from anywhere… dev.to Quick Tip: Function Expressions vs Function Declarations - SitePoint This article was peer reviewed by Jeff Mott. Thanks to all of SitePoint's peer reviewers for making SitePoint content… www.sitepoint.com JavaScript Function — Declaration vs Expression Functions are considered as First Class citizen in JavaScript and it is really important to be clear with the concept… medium.com Function Declarations vs. Function Expressions What is Function Statement/Declarations in JavaScript? medium.com Function Declarations vs. Function Expressions Lets start with a short quiz. What is alerted in each case?: Question 1: Question 2: Question 3: Question 4: If you… javascriptweblog.wordpress.com 16. Modules Edit description exploringjs.com ES modules: A cartoon deep-dive - Mozilla Hacks - the Web developer blog ES modules bring an official, standardized module system to JavaScript. With the release of Firefox 60 in May, all… hacks.mozilla.org Understanding ES6 Modules - SitePoint Almost every language has a concept of modules - a way to include functionality declared in one file within another… www.sitepoint.com An overview of ES6 Modules in JavaScript Introduction Until recently if you wanted to take full advantage of modules in JavaScript you needed to make use of… blog.cloud66.com ES6 Modules in Depth Welcome back to ES6 - “Oh, good. It's not another article about Unicode” - in Depth series. If you've never been around… ponyfoo.com How JavaScript works: Event loop and the rise of Async programming + 5 ways to better coding with… Welcome to post # 4 of the series dedicated to exploring JavaScript and its building components. In the process of… blog.sessionstack.com Tasks, microtasks, queues and schedules Edit description jakearchibald.com Visualising the JavaScript Event Loop with a Pizza Restaurant analogy Consider a pizza restaurant. There are two types of orders that we currently have from a single customer - one is an… dev.to✨♻️ JavaScript Visualized: Event Loop Oh boi the event loop. It's one of those things that every JavaScript developer has to deal with in one way or another… dev.to Scheduling: setTimeout and setInterval Edit description javascript.info Understanding How the Chrome V8 Engine Translates JavaScript into Machine Code Before diving deep into the core of Chrome's V8, first, let's get our fundamentals down. All of our systems consist of… medium.freecodecamp.org Understanding V8's Bytecode V8 is Google's open source JavaScript engine. Chrome, Node.js, and many other applications use V8. This article… medium.com A Brief History of Google's V8 JavaScript Engine Javascript has a reputation in developer circles as a terrible language. It's classless, loosely typed, and plagued by… www.mediacurrent.com JavaScript essentials: why you should know how the engine works This article is also available in Spanish. medium.freecodecamp.org JavaScript engine fundamentals: Shapes and Inline Caches This article describes some key fundamentals that are common to all JavaScript engines - and not just V8, the engine… mathiasbynens.be JavaScript engine fundamentals: optimizing prototypes This article describes some key fundamentals that are common to all JavaScript engines - and not just V8, the engine… mathiasbynens.be Elements kinds in V8 Note: If you prefer watching a presentation over reading articles, then enjoy the video below! JavaScript objects can… v8.dev Programming with JS: Bitwise Operations In this series of articles we take a look at different Computer Science topics from the prism of JavaScript. We've… hackernoon.com Using JavaScript's Bitwise Operators in Real Life Let's pretend we're machine code programmers! codeburst.io JavaScript Bitwise Operators - w3resource Bitwise operators perform an operation on the bitwise (0,1) representation of their arguments, rather than as decimal… www.w3resource.com JavaScript DOM Tutorial with Example Details JavaScript can access all the elements in a webpage making use of Document Object Model (DOM). In fact, the web… www.guru99.com What is the DOM? A reader recently wrote in asking me what the DOM was. They said they've heard it mentioned and alluded to, but aren't… css-tricks.com Traversing the DOM with JavaScript A good JavaScript developer needs to know how to traverse the DOM-it's the act of selecting an element from another… zellwk.com DOM tree The backbone of an HTML document is tags. According to the Document Object Model (DOM), every HTML tag is an object… javascript.info How to traverse the DOM in JavaScript Learn how to navigate your way through the DOM tree. javascript.plainenglish.io A Vanilla JS Guide On Mastering the DOM Note: The contents of this post are intended to be introductory and does not include use of any libraries like jQuery… dev.to How To Use Classes in JavaScript DigitalOcean JavaScript is a prototype-based language, and every object in JavaScript has a hidden internal property called… www.digitalocean.com Javascript Classes — Under The Hood Javascript classes are nothing but a syntactic sugar over existing prototype based inheritance and constructor… medium.com ES6 Classes - JavaScript January Object-Oriented Programming (OOP) can be a great way to organize your projects. Introduced with ES6, the javascript… www.javascriptjanuary.com Practical Ways to Write Better JavaScript Solid methods of improving your JS. Tagged with javascript, webdev, beginners, react. dev.to Better JavaScript with ES6, Pt. II: A Deep Dive into Classes Out with the Old, In with the new Let's be clear about one thing from the start: Under the hood, ES6 classes are not… scotch.io Understand the Factory Design Pattern in plain javascript The simplest way to understand Factory Design Pattern medium.com Factory Functions in JavaScript Aten Design Group As we move from an age of jQuery plugins and script drop-ins to a world of CommonJS and modular architectures it's… atendesigngroup.com The Factory Pattern in JS ES6 I'm trying to get the most out of all the new things in ES6 (ES2015). And I'm writing a new library where I need a… medium.com Class vs Factory function: exploring the way forward ECMAScript 2015 (aka ES6) comes with the class syntax, so now we have two competing patterns for creating objects. In… medium.freecodecamp.org Prototype in Javascript Codementor By default every function has a property name as prototype which is EMPTY ( by default). We can add properties and… www.codementor.io Prototypes in JavaScript In this post, we will discuss what are prototypes in JavaScript, how they help JavaScript in achieving the concepts of… betterprogramming.pub Prototype in JavaScript: it's quirky, but here's how it works The following four lines are enough to confuse most JavaScript developers: medium.freecodecamp.org Understanding JavaScript: Prototype and Inheritance Due to the amazing quantity of libraries, tools and all kinds of things that make your development easier, a lot of… hackernoon.com Understanding Classes (ES5) and Prototypal Inheritance in JavaScript In a nutshell the above snippet creates a Person class that can have multiple instances. By convention functional… dev.to _Master JavaScript Prototypes & _Inheritance__\ Inheritancecodeburst.io JavaScript's Prototypal Inheritance Explained Using CSS Prototypal inheritance is arguably the least understood aspect of JavaScript. Well the good news is that if you… medium.freecodecamp.org Demystifying ES6 Classes And Prototypal Inheritance In the early history of the JavaScript language, a cloud of animosity formed over the lack of a proper syntax for… scotch.io Intro To Prototypal Inheritance - JS In this article I will try to give an introduction to protypal inheritance. As an “optional” pre-requisite, you can… dev.to Let's Build Prototypal Inheritance in JS The idea for this post is pretty simple. I want to some extent build and with that, illustrate how prototypes work in… dev.to Understanding Prototypal Inheritance In JavaScript What Is Object-oriented Programming (OOP) Classical vs Prototypal Inheritance The Prototype Object And The Prototype… dev.to Object.create() - JavaScript MDN The Object.create() method creates a new object, using an existing object as the prototype of the newly created object… developer.mozilla.org Object.assign() - JavaScript MDN The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It… developer.mozilla.org Object.create in JavaScript The Object.create method is one of the methods to create a new object in JavaScript. medium.com Javascript Objects A New Way to Create Objects HTML Goodies There are a lot of ways to create Objects in JavaScript, perhaps even more to integrate inheritance into them. Just… www.htmlgoodies.com JavaScript Object Creation: Patterns and Best Practices - SitePoint Jeff Mott guides you through a step-by-step approach to JavaScript object creation - from object literals to factory… www.sitepoint.com Dealing With Objects in JavaScript With Object.assign, Object.keys and hasOwnProperty … This post is a sort of grab bag to help you explore a few very useful methods to help you manage your objects in… alligator.io Copying Objects in JavaScript DigitalOcean Objects are the fundamental blocks of JavaScript. An object is a collection of properties, and a property is an… scotch.io JavaScript: Object.assign() Veja nesse artigo como utilizar o Object.assign() do ECMAScript 6 codeburst.io How to deep clone a JavaScript object Copying objects in JavaScript can be tricky. Some ways perform a shallow copy, which is the default behavior in most of… flaviocopes.com How to Use Map, Filter, and Reduce in JavaScript Functional programming has been making quite a splash in the development world these days. And for good reason… code.tutsplus.com JavaScript — Learn to Chain Map, Filter, and Reduce Learn how to chain map, filter, and reduce in JavaScript codeburst.io Understanding map, filter and reduce in Javascript When working on Javascript projects you inevitably come across situations where you have to do some data manipulation… hackernoon.com Functional Programming in JS: map, filter, reduce (Pt. 5) Note: This is part of the “Javascript and Functional Programming” series on learning functional programming techniques… hackernoon.com JavaScript: Map, Filter, Reduce JavaScript's built-in map, filter, and reduce array methods are invaluable to a modern JavaScript developer. First… wsvincent.com A simple guide to help you understand closures in JavaScript Closures in JavaScript are one of those concepts that many struggle to get their heads around. In the following… medium.freecodecamp.org Understanding JavaScript Closures: A Practical Approach Learning a new language involves a series of steps, whereas its mastery is a product of patience, practice, mistakes… scotch.io Understanding JavaScript: Closures Why learn JavaScript in depth? hackernoon.com How to use JavaScript closures with confidence Using closures will be a piece of (chocolate) cake hackernoon.com JavaScript Closures by Example At some point you may have run into a problem when executing functions from within a for loop. The first time it… howchoo.com Higher-Order Functions :: Eloquent JavaScript Tzu-li and Tzu-ssu were boasting about the size of their latest programs. 'Two-hundred thousand lines,' said Tzu-li… eloquentjavascript.net Higher-Order Functions in JavaScript - SitePoint Continuing his look at functional programming in JavaScript, M. David Green examines higher-order functions and how… www.sitepoint.com Higher Order Functions: Using Filter, Map and Reduce for More Maintainable Code Higher order functions can help you to step up your JavaScript game by making your code more declarative. That is… medium.freecodecamp.org First-class and Higher Order Functions: Effective Functional JavaScript Functions: the killer JavaScript feature we never talk about. hackernoon.com Higher Order Functions in JavaScript Higher-order functions can be intimidating at first, but they're not that hard to learn. A higher-order function is… www.lullabot.com ES6 Promises: Patterns and Anti-Patterns When I first got started with NodeJS a few years ago, I was mortified by what is now affectionately known as "callback… medium.com A Simple Guide to ES6 Promises The woods are lovely, dark and deep. But I have promises to keep, and miles to go before I sleep. — Robert Frost codeburst.io The ES6 Promises A very helpful feature in ES6 codeburst.io ES6 Promises in Depth Promises are a very involved paradigm, so we'll take it slow. Here's a table of contents with the topics we'll cover in… ponyfoo.com Javascript Promises: An In-Depth Approach“Write down the syntax for promises on this sheet of paper”, is enough to give nightmares to a lot of junior and even… codeburst.io Promises - JavaScript concepts This is part of a series where I try to explain through each of 33 JS Concepts. This part corresponds to Promises… dev.to Javascript Promise 101 Knowing how Promise works in javascript will boost your development skill exponentially. Here I will share: I promise… dev.to Simplify JavaScript Promises I love promises. Not from people, but from JavaScript. Tweet Quote I love promises. Not from people, but from… dev.to The Lowdown on Promises A quick and concise guide on how Promises work in JavaScript medium.com⭐️🎀 JavaScript Visualized: Promises & Async/Await Ever had to deal with JS code that just… didn't run the way you expected it to? Maybe it seemed like functions got… dev.to How to escape async/await hell async/await freed us from callback hell, but people have started abusing it — leading to the birth of async/await hell. medium.freecodecamp.org Understanding JavaScript's async await Let's suppose we had code like the following. Here I'm wrapping an HTTP request in a Promise. The promise fulfills with… ponyfoo.com JavaScript Async/Await: Serial, Parallel and Complex Flow - TechBrij If you have experience on ASP.NET MVC then probably you are familiar with async/await keywords in C#. The same thing is… techbrij.com From JavaScript Promises to Async/Await: why bother? In this tutorial, we will cover why we need async/await when we could achieve the same fit with JavaScript Promises, to… blog.pusher.com Flow Control in Modern JS: Callbacks to Promises to Async/Await - SitePoint JavaScript is regularly claimed to be asynchronous. What does that mean? How does it affect development? How has the… www.sitepoint.com Time Complexity Analysis in JavaScript An algorithm is a self-contained step-by-step set of instructions to solve a problem. It takes time for these steps to… www.jenniferbland.com Algorithms in plain English: time complexity and Big-O notation Every good developer has time on their mind. They want to give their users more of it, so they can do all those things… medium.freecodecamp.org An Introduction to Big O Notation Big O notation is a big topic, and its universal importance stems from the fact that it describes the efficiency of… dev.to[Crizstian/data-structure-and-algorithms-with-ES6 Num Type Exercises Description 10.- Graph Data Structure 2 A graph consists of a set of vertices and a set of edges. A… github.com]( https://github.com/Crizstian/data-structure-and-algorithms-with-ES6 " https://github.com/Crizs https://github.com/bgoonz/03-fetch-data https://github.com/bgoonz/gatsby-netlify-cms-norwex https://hub.com/bgoonz/React-movie-app https://github.com/bgoonz/Exploring-Promises https://hub.com/bgoonz/vscode-customized-config https://github.com/bgoonz/a-whole-bunch-o-gatsby-templates https://github.com/bgoonz/gatsby-react-portfolio https://hub.com/bgoonz/react-redux-medium-clone https://github.com/bgoonz/express-API-template https://hub.com/bgoonz/vscode-Extension-readmes https://github.com/bgoonz/activity-box https://github.com/bgoonz/GIT-CDN-FILES https://hub.com/bgoonz/react-redux-notes-v5 https://github.com/bgoonz/Express-basic-server-template https://hub.com/bgoonz/web-crawler-node https://github.com/bgoonz/All-Undergrad-Archive https://github.com/bgoonz/GIT-HTML-PREVIEW-TOOL https://hub.com/bgoonz/react-redux-registration-login-example https://github.com/bgoonz/express-knex-postgres-boilerplate https://hub.com/bgoonz/web-dev-interview-prep-quiz-website https://github.com/bgoonz/alternate-blog-theme https://github.com/bgoonz/gitbook https://hub.com/bgoonz/React Notes V3 https://github.com/bgoonz/EXPRESS-NOTES https://hub.com/bgoonz/web-dev-notes-resource-site https://github.com/bgoonz/anki-cards https://github.com/bgoonz/github-readme-stats https://hub.com/bgoonz/Recursion-Practice-Website https://github.com/bgoonz/fast-fourier-transform- https://hub.com/bgoonz/web-dev-setup-checker https://github.com/bgoonz/ask-me-anything https://github.com/bgoonz/github-reference-repo https://hub.com/bgoonz/Regex-and-Express-JS https://github.com/bgoonz/form-builder-vanilla-js https://hub.com/bgoonz/WEB-DEV-TOOLS-HUB https://github.com/bgoonz/atlassian-templates https://github.com/bgoonz/GoalsTracker https://hub.com/bgoonz/repo-utils https://github.com/bgoonz/Front-End-Frameworks-Practice https://hub.com/bgoonz/web-dev-utils-package https://github.com/bgoonz/Authentication-Notes https://github.com/bgoonz/graphql-experimentation https://hub.com/bgoonz/resume-cv-portfolio-samples https://github.com/bgoonz/full-stack-react-redux https://hub.com/bgoonz/WebAudioDaw https://github.com/bgoonz/bash-commands-walkthrough https://github.com/bgoonz/https __mihirbeg.com https://hub.com/bgoonz/Revamped-Automatic-Guitar-Effect-Triggering https://github.com/bgoonz/Full-Text-Search https://hub.com/bgoonz/website https://github.com/bgoonz/bash-config-backup https://github.com/bgoonz/iframe-showcase https://hub.com/bgoonz/scope-closure-context https://github.com/bgoonz/Games https://github.com/bgoonz/Data-Structures-Algos-Codebase https://github.com/bgoonz/bash-shell-utility-functions https://github.com/bgoonz/Image-Archive-Traning-Data https://hub.com/bgoonz/Shell-Script-Practice https://github.com/bgoonz/MihirBegMusicV3 https://github.com/bgoonz/DATA STRUC PYTHON_NOTES https://github.com/bgoonz/bass-station https://github.com/bgoonz/Independent-Blog-Entries https://hub.com/bgoonz/site-analysis https://github.com/bgoonz/Mihir Beg Final https://github.com/bgoonz/design-home-page-with-routes-bq5v7k https://github.com/bgoonz/bgoonz https://github.com/bgoonz/INTERVIEW-PREP-COMPLETE https://hub.com/bgoonz/sorting-algorithms https://github.com/bgoonz/mini-project-showcase https://github.com/bgoonz/docs-collection https://github.com/bgoonz/BGOONZBLOG2.0STABLE https://github.com/bgoonz/JAMSTACK-TEMPLATES https://hub.com/bgoonz/sorting-algos https://github.com/bgoonz/Music-Theory-n-Web-Synth-Keyboard https://github.com/bgoonz/Documentation-site-react https://github.com/bgoonz/BGOONZ BLOG 2.0 https://github.com/bgoonz/Javascript-Best-Practices_--Tools https://hub.com/bgoonz/sqlite3-nodejs-demo https://github.com/bgoonz/my-gists https://github.com/bgoonz/DS-ALGO-OFFICIAL https://github.com/bgoonz/Binary-Search https://github.com/bgoonz/jsanimate https://hub.com/bgoonz/stalk-photos-web-assets https://github.com/bgoonz/My-Medium-Blog https://github.com/bgoonz/DS-AND-ALGO-Notes-P2 https://github.com/bgoonz/blog-2.o-versions https://github.com/bgoonz/Jupyter-Notebooks https://hub.com/bgoonz/Standalone-Metranome https://github.com/bgoonz/nextjs-netlify-blog-template https://github.com/bgoonz/ecommerce-interactive https://github.com/bgoonz/blog-templates https://github.com/bgoonz/Lambda https://hub.com/bgoonz/Star-wars-API-Promise-take2 https://github.com/bgoonz/norwex-coff-ecom https://github.com/bgoonz/embedable-repl-and-integrated-code-space-playground https://github.com/bgoonz/blog-w-comments https://github.com/bgoonz/Lambda-Resource-Static-Assets https://hub.com/bgoonz/Static-Study-Site https://github.com/bgoonz/old-c-and-cpp-repos-from-undergrad https://github.com/bgoonz/excel2html-table https://github.com/bgoonz/Blog2.0-August-Super-Stable https://github.com/bgoonz/learning-nextjs https://hub.com/bgoonz/styling-templates https://github.com/bgoonz/old-code-from-undergrad https://github.com/bgoonz/bootstrap-sidebar-template https://github.com/bgoonz/Learning-Redux https://hub.com/bgoonz/supertemp https://github.com/bgoonz/picture-man-bob-v2 https://github.com/bgoonz/callbacks https://github.com/bgoonz/Links-Shortcut-Site https://hub.com/bgoonz/Ternary-converter https://github.com/bgoonz/Project-Showcase https://github.com/bgoonz/Comments https://github.com/bgoonz/live-examples https://hub.com/bgoonz/TetrisJS https://github.com/bgoonz/promises-with-async-and-await https://github.com/bgoonz/commercejs-nextjs-demo-store https://github.com/bgoonz/live-form https://hub.com/bgoonz/TexTools https://github.com/bgoonz/psql-practice https://github.com/bgoonz/Common-npm-Readme-Compilation https://github.com/bgoonz/loadash-es6-refactor https://hub.com/bgoonz/The-Algorithms https://github.com/bgoonz/python-playground-embed https://github.com/bgoonz/Comparing-Web-Development-Bootcamps-2021 https://github.com/bgoonz/markdown-css https://hub.com/bgoonz/TRASH https://github.com/bgoonz/python-practice-notes https://github.com/bgoonz/Connect-Four-Final-Version https://github.com/bgoonz/Markdown-Templates https://hub.com/bgoonz/Triggered-Guitar-Effects-Platform https://github.com/bgoonz/python-scripts https://github.com/bgoonz/convert-folder-contents-2-website https://github.com/bgoonz/meditation-app https://hub.com/bgoonz/Useful-Snippets-js https://github.com/bgoonz/PYTHON_PRAC https://github.com/bgoonz/Copy-2-Clipboard-jQuery https://github.com/bgoonz/MihirBegMusicLab https://hub.com/bgoonz/UsefulResourceRepo2.0 https://github.com/bgoonz/random-list-of-embedable-content
    https://bgoonz-blog.netlify.app/images/code.png
  • Algorithms & Data Structures
    Algorithms & Data Structures Fundamental Data Structures In JavaScript Algorithms The Algos Bgoonz Branch Fundamental Data Structures In JavaScript Data structures in JavaScript Here's a website I created to practice data structures! directory Edit description ds-algo-official-c3dw6uapg-bgoonz.vercel.app Here's the repo that the website is built on: bgoonz/DS-ALGO-OFFICIAL Navigation ####Author:Bryan Guner Big O notation is the language we use for talking about how long an algorithm takes… github.com Resources (article content below): Videos Abdul Bari: YouTubeChannel for Algorithms Data Structures and algorithms Data Structures and algorithms Course Khan Academy Data structures by mycodeschool Pre-requisite for this lesson is good understanding of pointers in C. MIT 6.006: Intro to Algorithms(2011) Data Structures and Algorithms by Codewithharry Books Introduction to Algorithms by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein Competitive Programming 3 by Steven Halim and Felix Halim Competitive Programmers Hand Book Beginner friendly hand book for competitive programmers. Data Structures and Algorithms Made Easy by Narasimha Karumanchi Learning Algorithms Through Programming and Puzzle Solving by Alexander Kulikov and Pavel Pevzner Coding practice LeetCode InterviewBit Codility HackerRank Project Euler Spoj Google Code Jam practice problems HackerEarth Top Coder CodeChef Codewars CodeSignal CodeKata Firecode Courses Master the Coding Interview: Big Tech (FAANG) Interviews Course by Andrei and his team. Common Python Data Structures Data structures are the fundamental constructs around which you build your programs. Each data structure provides a particular way of organizing data so it can be accessed efficiently, depending on your use case. Python ships with an extensive set of data structures in its standard library. Fork CPP A good course for beginners. EDU Advanced course. C++ For Programmers Learn features and constructs for C++. Guides GeeksForGeeks — A CS portal for geeks Learneroo — Algorithms Top Coder tutorials Infoarena training path (RO) Steven & Felix Halim — Increasing the Lower Bound of Programming Contests (UVA Online Judge) space The space complexity represents the memory consumption of a data structure. As for most of the things in life, you can't have it all, so it is with the data structures. You will generally need to trade some time for space or the other way around. time The time complexity for a data structure is in general more diverse than its space complexity. Several operations In contrary to algorithms, when you look at the time complexity for data structures you need to express it for several operations that you can do with data structures. It can be adding elements, deleting elements, accessing an element or even searching for an element. Dependent on data Something that data structure and algorithms have in common when talking about time complexity is that they are both dealing with data. When you deal with data you become dependent on them and as a result the time complexity is also dependent of the data that you received. To solve this problem we talk about 3 different time complexity. The best-case complexity: when the data looks the best The worst-case complexity: when the data looks the worst The average-case complexity: when the data looks average Big O notation The complexity is usually expressed with the Big O notation. The wikipedia page about this subject is pretty complex but you can find here a good summary of the different complexity for the most famous data structures and sorting algorithms. The Array data structure Definition An Array data structure, or simply an Array, is a data structure consisting of a collection of elements (values or variables), each identified by at least one array index or key. The simplest type of data structure is a linear array, also called one-dimensional array. From Wikipedia Arrays are among the oldest and most important data structures and are used by every program. They are also used to implement many other data structures. Complexity Average Access Search Insertion Deletion O(1) O(n) O(1) O(n) class ArrayADT { constructor() { this.array = []; } add(data) { this.array.push(data); } remove(data) { this.array = this.array.filter((current) => current !== data); } search(data) { const foundIndex = this.array.indexOf(data); if (foundIndex === -1) { return foundIndex; } return null; } getAtIndex(index) { return this.array[index]; } length() { return this.array.length; } print() { console.log(this.array.join(' ')); } } const array = new ArrayADT(); console.log('const array = new ArrayADT();: ', array); console.log('-------------------------------'); console.log('array.add(1): ', array.add(1)); array.add(3); array.add(4); console.log('array.add(2);: ', array.add(2), 'array.add(3);', array.add(3), 'array.add(4); ', array.add(4)); console.log('-------------------------------'); array.print(); console.log('-------------------------------'); console.log('search 3 gives index 2:', array.search(3)); console.log('-------------------------------'); console.log('getAtIndex 2 gives 3:', array.getAtIndex(2)); console.log('-------------------------------'); console.log('length is 4:', array.length()); console.log('-------------------------------'); array.remove(3); array.print(); console.log('-------------------------------'); array.add(5); array.add(5); array.print(); console.log('-------------------------------'); array.remove(5); array.print(); console.log('-------------------------------'); /* ~ final : (master) node 01-array.js const array = new ArrayADT();: ArrayADT { array: [] } ------------------------------- array.add(1): undefined array.add(2);: undefined array.add(3); undefined array.add(4); undefined ------------------------------- 1 3 4 2 3 4 ------------------------------- search 3 gives index 2: null ------------------------------- getAtIndex 2 gives 3: 4 ------------------------------- length is 4: 6 ------------------------------- 1 4 2 4 ------------------------------- 1 4 2 4 5 5 ------------------------------- 1 4 2 4 ------------------------------- ~ final : (master) */ indexvalue0 … this is the first value, stored at zero position The index of an array runs in sequence This could be useful for storing data that are required to be ordered, such as rankings or queues In JavaScript, array's value could be mixed; meaning value of each index could be of different data, be it String, Number or even Objects // 1. Creating Arrays let firstArray = ["a","b","c"]; let secondArray = ["d","e","f"]; // 2. Access an Array Item console.log(firstArray[0]); // Results: "a" // 3. Loop over an Array firstArray.forEach(function(item, index, array){ console.log(item, index); }); // Results: // a 0 // b 1 // c 2 // 4. Add new item to END of array secondArray.push('g'); console.log(secondArray); // Results: ["d","e","f", "g"] // 5. Remove item from END of array secondArray.pop(); console.log(secondArray); // Results: ["d","e","f"] // 6. Remove item from FRONT of array secondArray.shift(); console.log(secondArray); // Results: ["e","f"] // 7. Add item to FRONT of array secondArray.unshift("d"); console.log(secondArray); // Results: ["d","e","f"] // 8. Find INDEX of an item in array let position = secondArray.indexOf('f'); // Results: 2 // 9. Remove Item by Index Position secondArray.splice(position, 1); console.log(secondArray); // Note, the second argument, in this case "1", // represent the number of array elements to be removed // Results: ["d","e"] // 10. Copy an Array let shallowCopy = secondArray.slice(); console.log(secondArray); console.log(shallowCopy); // Results: ShallowCopy === ["d","e"] // 11. JavaScript properties that BEGIN with a digit MUST be accessed using bracket notation renderer.3d.setTexture(model, 'character.png'); // a syntax error renderer['3d'].setTexture(model, 'character.png'); // works properly // 12. Combine two Arrays let thirdArray = firstArray.concat(secondArray); console.log(thirdArray); // ["a","b","c", "d", "e"]; // 13. Combine all Array elements into a string console.log(thirdArray.join()); // Results: a,b,c,d,e console.log(thirdArray.join('')); // Results: abcde console.log(thirdArray.join('-')); // Results: a-b-c-d-e // 14. Reversing an Array (in place, i.e. destructive) console.log(thirdArray.reverse()); // ["e", "d", "c", "b", "a"] // 15. sort let unsortedArray = ["Alphabet", "Zoo", "Products", "Computer Science", "Computer"]; console.log(unsortedArray.sort()); // Results: ["Alphabet", "Computer", "Computer Science", "Products", "Zoo" ] 2. Objects Think of objects as a logical grouping of a bunch of properties. Properties could be some variable that it's storing or some methods that it's using. I also visualize an object as a table. The main difference is that object's "index" need not be numbers and is not necessarily sequenced.// 16. Creating an Object let newObj = { name: "I'm an object", values: [1, 10, 11, 20], others: '', '1property': 'example of property name starting with digit' }; // 17. Figure out what keys/properties are in an object console.log(Object.keys(newObj)); // Results: [ 'name', 'values', 'others', '1property' ] // 18. Show all values stored in the object console.log(Object.values(newObj)); // Results: // [ 'I\'m an object', // [ 1, 10, 11, 20 ], // '', // 'example of property name starting with digit' ] // 19. Show all key and values of the object for (let [key, value] of Object.entries(newObj)) { console.log(`${key}: ${value}`); } // Results: // name: I'm an object // values: 1,10,11,20 // others: // 1property: example of property name starting with digit // 20. Accessing Object's Properties // Two different ways to access properties, both produce same results console.log(newObj.name); console.log(newObj['name']); // But if the property name starts with a digit, // we CANNOT use dot notation console.log(newObj['1property']); // 21. Adding a Method to an Object newObj.helloWorld = function () { console.log('Hello World from inside an object!'); }; // 22. Invoking an Object's Method newObj.helloWorld(); The Hash Table Definition A Hash Table (Hash Map) is a data structure used to implement an associative array, a structure that can map keys to values. A Hash Table uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found. From Wikipedia Hash Tables are considered the more efficient data structure for lookup and for this reason, they are widely used. Complexity Average Access Search Insertion Deletion O(1) O(1) O(1) The code Note, here I am storing another object for every hash in my Hash Table. class HashTable { constructor(size) { this.values = {}; this.numberOfValues = 0; this.size = size; } add(key, value) { let hash = this.calculateHash(key); if (!this.values.hasOwnProperty(hash)) { this.values[hash] = {}; } if (!this.values[hash].hasOwnProperty(key)) { this.numberOfValues++; } this.values[hash][key] = value; } remove(key) { let hash = this.calculateHash(key); if (this.values.hasOwnProperty(hash) && this.values[hash].hasOwnProperty(key)) { delete this.values[hash][key]; this.numberOfValues--; } } calculateHash(key) { return key.toString().length % this.size; } search(key) { let hash = this.calculateHash(key); if (this.values.hasOwnProperty(hash) && this.values[hash].hasOwnProperty(key)) { return this.values[hash][key]; } else { return null; } } length() { return this.numberOfValues; } print() { let string = ''; for (let value in this.values) { for (let key in this.values[value]) { string += this.values[value][key] + ' '; } } console.log(string.trim()); } } let hashTable = new HashTable(3); hashTable.add('first', 1); hashTable.add('second', 2); hashTable.add('third', 3); hashTable.add('fourth', 4); hashTable.add('fifth', 5); hashTable.print(); // => 2 4 1 3 5 console.log('length gives 5:', hashTable.length()); // => 5 console.log('search second gives 2:', hashTable.search('second')); // => 2 hashTable.remove('fourth'); hashTable.remove('first'); hashTable.print(); // => 2 3 5 console.log('length gives 3:', hashTable.length()); // => 3 /* ~ js-files : (master) node hash.js 2 4 1 3 5 length gives 5: 5 search second gives 2: 2 2 3 5 length gives 3: 3 */ The Set Sets Sets are pretty much what it sounds like. It's the same intuition as Set in Mathematics. I visualize Sets as Venn Diagrams.// 23. Creating a new Set let newSet = new Set(); // 24. Adding new elements to a set newSet.add(1); // Set[1] newSet.add('text'); // Set[1, "text"] // 25. Check if element is in set newSet.has(1); // true // 24. Check size of set console.log(newSet.size); // Results: 2 // 26. Delete element from set newSet.delete(1); // Set["text"] // 27. Set Operations: isSuperSet function isSuperset(set, subset) { for (let elem of subset) { if (!set.has(elem)) { return false; } } return true; } // 28. Set Operations: union function union(setA, setB) { let _union = new Set(setA); for (let elem of setB) { _union.add(elem); } return _union; } // 29. Set Operations: intersection function intersection(setA, setB) { let _intersection = new Set(); for (let elem of setB) { if (setA.has(elem)) { _intersection.add(elem); } } return _intersection; } // 30. Set Operations: symmetricDifference function symmetricDifference(setA, setB) { let _difference = new Set(setA); for (let elem of setB) { if (_difference.has(elem)) { _difference.delete(elem); } else { _difference.add(elem); } } return _difference; } // 31. Set Operations: difference function difference(setA, setB) { let _difference = new Set(setA); for (let elem of setB) { _difference.delete(elem); } return _difference; } // Examples let setA = new Set([1, 2, 3, 4]); let setB = new Set([2, 3]); let setC = new Set([3, 4, 5, 6]); console.log(isSuperset(setA, setB)); // => true console.log(union(setA, setC)); // => Set [1, 2, 3, 4, 5, 6] console.log(intersection(setA, setC)); // => Set [3, 4] console.log(symmetricDifference(setA, setC)); // => Set [1, 2, 5, 6] console.log(difference(setA, setC)); // => Set [1, 2] Definition A Set is an abstract data type that can store certain values, without any particular order, and no repeated values. It is a computer implementation of the mathematical concept of a finite Set. From Wikipedia The Set data structure is usually used to test whether elements belong to set of values. Rather then only containing elements, Sets are more used to perform operations on multiple values at once with methods such as union, intersect, etc… Complexity Average Access Search Insertion Deletion O(n) O(n) O(n) The code function Set() { this.values = []; this.numberOfValues = 0; } Set.prototype.add = function (value) { if (!~this.values.indexOf(value)) { this.values.push(value); this.numberOfValues++; } }; Set.prototype.remove = function (value) { let index = this.values.indexOf(value); if (~index) { this.values.splice(index, 1); this.numberOfValues--; } }; Set.prototype.contains = function (value) { return this.values.indexOf(value) !== -1; }; Set.prototype.union = function (set) { let newSet = new Set(); set.values.forEach(function (value) { newSet.add(value); }); this.values.forEach(function (value) { newSet.add(value); }); return newSet; }; Set.prototype.intersect = function (set) { let newSet = new Set(); this.values.forEach(function (value) { if (set.contains(value)) { newSet.add(value); } }); return newSet; }; Set.prototype.difference = function (set) { let newSet = new Set(); this.values.forEach(function (value) { if (!set.contains(value)) { newSet.add(value); } }); return newSet; }; Set.prototype.isSubset = function (set) { return set.values.every(function (value) { return this.contains(value); }, this); }; Set.prototype.length = function () { return this.numberOfValues; }; Set.prototype.print = function () { console.log(this.values.join(' ')); }; let set = new Set(); set.add(1); set.add(2); set.add(3); set.add(4); set.print(); // => 1 2 3 4 set.remove(3); set.print(); // => 1 2 4 console.log('contains 4 is true:', set.contains(4)); // => true console.log('contains 3 is false:', set.contains(3)); // => false console.log('---'); let set1 = new Set(); set1.add(1); set1.add(2); let set2 = new Set(); set2.add(2); set2.add(3); let set3 = set2.union(set1); set3.print(); // => 1 2 3 let set4 = set2.intersect(set1); set4.print(); // => 2 let set5 = set.difference(set3); // 1 2 4 diff 1 2 3 set5.print(); // => 4 let set6 = set3.difference(set); // 1 2 3 diff 1 2 4 set6.print(); // => 3 console.log('set1 subset of set is true:', set.isSubset(set1)); // => true console.log('set2 subset of set is false:', set.isSubset(set2)); // => false console.log('set1 length gives 2:', set1.length()); // => 2 console.log('set3 length gives 3:', set3.length()); // => 3 The Singly Linked List Definition A Singly Linked List is a linear collection of data elements, called nodes pointing to the next node by means of pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence. Linked Lists are among the simplest and most common data structures because it allows for efficient insertion or removal of elements from any position in the sequence. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code function Node(data) { this.data = data; this.next = null; } function SinglyLinkedList() { this.head = null; this.tail = null; this.numberOfValues = 0; } SinglyLinkedList.prototype.add = function (data) { let node = new Node(data); if (!this.head) { this.head = node; this.tail = node; } else { this.tail.next = node; this.tail = node; } this.numberOfValues++; }; SinglyLinkedList.prototype.remove = function (data) { let previous = this.head; let current = this.head; while (current) { if (current.data === data) { if (current === this.head) { this.head = this.head.next; } if (current === this.tail) { this.tail = previous; } previous.next = current.next; this.numberOfValues--; } else { previous = current; } current = current.next; } }; SinglyLinkedList.prototype.insertAfter = function (data, toNodeData) { let current = this.head; while (current) { if (current.data === toNodeData) { let node = new Node(data); if (current === this.tail) { this.tail.next = node; this.tail = node; } else { node.next = current.next; current.next = node; } this.numberOfValues++; } current = current.next; } }; SinglyLinkedList.prototype.traverse = function (fn) { let current = this.head; while (current) { if (fn) { fn(current); } current = current.next; } }; SinglyLinkedList.prototype.length = function () { return this.numberOfValues; }; SinglyLinkedList.prototype.print = function () { let string = ''; let current = this.head; while (current) { string += current.data + ' '; current = current.next; } console.log(string.trim()); }; let singlyLinkedList = new SinglyLinkedList(); singlyLinkedList.print(); // => '' singlyLinkedList.add(1); singlyLinkedList.add(2); singlyLinkedList.add(3); singlyLinkedList.add(4); singlyLinkedList.print(); // => 1 2 3 4 console.log('length is 4:', singlyLinkedList.length()); // => 4 singlyLinkedList.remove(3); // remove value singlyLinkedList.print(); // => 1 2 4 singlyLinkedList.remove(9); // remove non existing value singlyLinkedList.print(); // => 1 2 4 singlyLinkedList.remove(1); // remove head singlyLinkedList.print(); // => 2 4 singlyLinkedList.remove(4); // remove tail singlyLinkedList.print(); // => 2 console.log('length is 1:', singlyLinkedList.length()); // => 1 singlyLinkedList.add(6); singlyLinkedList.print(); // => 2 6 singlyLinkedList.insertAfter(3, 2); singlyLinkedList.print(); // => 2 3 6 singlyLinkedList.insertAfter(4, 3); singlyLinkedList.print(); // => 2 3 4 6 singlyLinkedList.insertAfter(5, 9); // insertAfter a non existing node singlyLinkedList.print(); // => 2 3 4 6 singlyLinkedList.insertAfter(5, 4); singlyLinkedList.insertAfter(7, 6); // insertAfter the tail singlyLinkedList.print(); // => 2 3 4 5 6 7 singlyLinkedList.add(8); // add node with normal method singlyLinkedList.print(); // => 2 3 4 5 6 7 8 console.log('length is 7:', singlyLinkedList.length()); // => 7 singlyLinkedList.traverse(function (node) { node.data = node.data + 10; }); singlyLinkedList.print(); // => 12 13 14 15 16 17 18 singlyLinkedList.traverse(function (node) { console.log(node.data); }); // => 12 13 14 15 16 17 18 console.log('length is 7:', singlyLinkedList.length()); // => 7 The Doubly Linked List Definition A Doubly Linked List is a linked data structure that consists of a set of sequentially linked records called nodes. Each node contains two fields, called links, that are references to the previous and to the next node in the sequence of nodes. From Wikipedia Having two node links allow traversal in either direction but adding or removing a node in a doubly linked list requires changing more links than the same operations on a Singly Linked List. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code class Node { constructor(data) { this.data = data; this.previous = null; this.next = null; } } class DoublyLinkedList { constructor() { this.head = null; this.tail = null; this.numberOfValues = 0; } add(data) { let node = new Node(data); if (!this.head) { this.head = node; this.tail = node; } else { node.previous = this.tail; this.tail.next = node; this.tail = node; } this.numberOfValues++; } remove(data) { let current = this.head; while (current) { if (current.data === data) { if (current === this.head && current === this.tail) { this.head = null; this.tail = null; } else if (current === this.head) { this.head = this.head.next; this.head.previous = null; } else if (current === this.tail) { this.tail = this.tail.previous; this.tail.next = null; } else { current.previous.next = current.next; current.next.previous = current.previous; } this.numberOfValues--; } current = current.next; } } insertAfter(data, toNodeData) { let current = this.head; while (current) { if (current.data === toNodeData) { let node = new Node(data); if (current === this.tail) { this.add(data); } else { current.next.previous = node; node.previous = current; node.next = current.next; current.next = node; this.numberOfValues++; } } current = current.next; } } traverse(fn) { let current = this.head; while (current) { if (fn) { fn(current); } current = current.next; } } traverseReverse(fn) { let current = this.tail; while (current) { if (fn) { fn(current); } current = current.previous; } } length() { return this.numberOfValues; } print() { let string = ""; let current = this.head; while (current) { string += current.data + " "; current = current.next; } console.log(string.trim()); } } let doublyLinkedList = new DoublyLinkedList(); doublyLinkedList.print(); // => '' doublyLinkedList.add(1); doublyLinkedList.add(2); doublyLinkedList.add(3); doublyLinkedList.add(4); doublyLinkedList.print(); // => 1 2 3 4 console.log("length is 4:", doublyLinkedList.length()); // => 4 doublyLinkedList.remove(3); // remove value doublyLinkedList.print(); // => 1 2 4 doublyLinkedList.remove(9); // remove non existing value doublyLinkedList.print(); // => 1 2 4 doublyLinkedList.remove(1); // remove head doublyLinkedList.print(); // => 2 4 doublyLinkedList.remove(4); // remove tail doublyLinkedList.print(); // => 2 console.log("length is 1:", doublyLinkedList.length()); // => 1 doublyLinkedList.remove(2); // remove tail, the list should be empty doublyLinkedList.print(); // => '' console.log("length is 0:", doublyLinkedList.length()); // => 0 doublyLinkedList.add(2); doublyLinkedList.add(6); doublyLinkedList.print(); // => 2 6 doublyLinkedList.insertAfter(3, 2); doublyLinkedList.print(); // => 2 3 6 doublyLinkedList.traverseReverse(function (node) { console.log(node.data); }); doublyLinkedList.insertAfter(4, 3); doublyLinkedList.print(); // => 2 3 4 6 doublyLinkedList.insertAfter(5, 9); // insertAfter a non existing node doublyLinkedList.print(); // => 2 3 4 6 doublyLinkedList.insertAfter(5, 4); doublyLinkedList.insertAfter(7, 6); // insertAfter the tail doublyLinkedList.print(); // => 2 3 4 5 6 7 doublyLinkedList.add(8); // add node with normal method doublyLinkedList.print(); // => 2 3 4 5 6 7 8 console.log("length is 7:", doublyLinkedList.length()); // => 7 doublyLinkedList.traverse(function (node) { node.data = node.data + 10; }); doublyLinkedList.print(); // => 12 13 14 15 16 17 18 doublyLinkedList.traverse(function (node) { console.log(node.data); }); // => 12 13 14 15 16 17 18 console.log("length is 7:", doublyLinkedList.length()); // => 7 doublyLinkedList.traverseReverse(function (node) { console.log(node.data); }); // => 18 17 16 15 14 13 12 doublyLinkedList.print(); // => 12 13 14 15 16 17 18 console.log("length is 7:", doublyLinkedList.length()); // => 7 /* ~ js-files : (master) node double-linked-list.js 1 2 3 4 length is 4: 4 1 2 4 1 2 4 2 4 2 length is 1: 1 length is 0: 0 2 6 2 3 6 6 3 2 2 3 4 6 2 3 4 6 2 3 4 5 6 7 2 3 4 5 6 7 8 length is 7: 7 12 13 14 15 16 17 18 12 13 14 15 16 17 18 length is 7: 7 18 17 16 15 14 13 12 12 13 14 15 16 17 18 length is 7: 7 ~ js-files : (master) */ The Stack Definition A Stack is an abstract data type that serves as a collection of elements, with two principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed. The order in which elements come off a Stack gives rise to its alternative name, LIFO (for last in, first out). From Wikipedia A Stack often has a third method peek which allows to check the last pushed element without popping it. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(1) The code function Stack() { this.stack = []; } Stack.prototype.push = function(value) { this.stack.push(value); }; Stack.prototype.pop = function() { return this.stack.pop(); }; Stack.prototype.peek = function() { return this.stack[this.stack.length - 1]; }; Stack.prototype.length = function() { return this.stack.length; }; Stack.prototype.print = function() { console.log(this.stack.join(' ')); }; let stack = new Stack(); stack.push(1); stack.push(2); stack.push(3); stack.print(); // => 1 2 3 console.log('length is 3:', stack.length()); // => 3 console.log('peek is 3:', stack.peek()); // => 3 console.log('pop is 3:', stack.pop()); // => 3 stack.print(); // => 1 2 console.log('pop is 2:', stack.pop()); // => 2 console.log('length is 1:', stack.length()); // => 1 console.log('pop is 1:', stack.pop()); // => 1 stack.print(); // => '' console.log('peek is undefined:', stack.peek()); // => undefined console.log('pop is undefined:', stack.pop()); // => undefined The Queue Definition A Queue is a particular kind of abstract data type or collection in which the entities in the collection are kept in order and the principal operations are the addition of entities to the rear terminal position, known as enqueue, and removal of entities from the front terminal position, known as dequeue. This makes the Queue a First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the Queue will be the first one to be removed. As for the Stack data structure, a peek operation is often added to the Queue data structure. It returns the value of the front element without dequeuing it. Complexity Average Access Search Insertion Deletion O(n) O(n) O(1) O(n) The code function Queue() { this.queue = []; } Queue.prototype.enqueue = function(value) { this.queue.push(value); }; Queue.prototype.dequeue = function() { return this.queue.shift(); }; Queue.prototype.peek = function() { return this.queue[0]; }; Queue.prototype.length = function() { return this.queue.length; }; Queue.prototype.print = function() { console.log(this.queue.join(' ')); }; let queue = new Queue(); queue.enqueue(1); queue.enqueue(2); queue.enqueue(3); queue.print(); // => 1 2 3 console.log('length is 3:', queue.length()); // => 3 console.log('peek is 1:', queue.peek()); // => 3 console.log('dequeue is 1:', queue.dequeue()); // => 1 queue.print(); // => 2 3 console.log('dequeue is 2:', queue.dequeue()); // => 2 console.log('length is 1:', queue.length()); // => 1 console.log('dequeue is 3:', queue.dequeue()); // => 3 queue.print(); // => '' console.log('peek is undefined:', queue.peek()); // => undefined console.log('dequeue is undefined:', queue.dequeue()); // => undefined The Tree Definition A Tree is a widely used data structure that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node. A tree data structure can be defined recursively as a collection of nodes (starting at a root node), where each node is a data structure consisting of a value, together with a list of references to nodes (the "children"), with the constraints that no reference is duplicated, and none points to the root node. From Wikipedia Complexity Average Access Search Insertion Deletion O(n) O(n) O(n) O(n) To get a full overview of the time and space complexity of the Tree data structure, have a look to this excellent Big O cheat sheet. The code function Node(data) { this.data = data; this.children = []; } function Tree() { this.root = null; } Tree.prototype.add = function(data, toNodeData) { let node = new Node(data); let parent = toNodeData ? this.findBFS(toNodeData) : null; if(parent) { parent.children.push(node); } else { if(!this.root) { this.root = node; } else { return 'Root node is already assigned'; } } }; Tree.prototype.remove = function(data) { if(this.root.data === data) { this.root = null; } let queue = [this.root]; while(queue.length) { let node = queue.shift(); for(let i = 0; i < node.children.length; i++) { if(node.children[i].data === data) { node.children.splice(i, 1); } else { queue.push(node.children[i]); } } } }; Tree.prototype.contains = function(data) { return this.findBFS(data) ? true : false; }; Tree.prototype.findBFS = function(data) { let queue = [this.root]; while(queue.length) { let node = queue.shift(); if(node.data === data) { return node; } for(let i = 0; i < node.children.length; i++) { queue.push(node.children[i]); } } return null; }; Tree.prototype._preOrder = function(node, fn) { if(node) { if(fn) { fn(node); } for(let i = 0; i < node.children.length; i++) { this._preOrder(node.children[i], fn); } } }; Tree.prototype._postOrder = function(node, fn) { if(node) { for(let i = 0; i < node.children.length; i++) { this._postOrder(node.children[i], fn); } if(fn) { fn(node); } } }; Tree.prototype.traverseDFS = function(fn, method) { let current = this.root; if(method) { this['_' + method](current, fn); } else { this._preOrder(current, fn); } }; Tree.prototype.traverseBFS = function(fn) { let queue = [this.root]; while(queue.length) { let node = queue.shift(); if(fn) { fn(node); } for(let i = 0; i < node.children.length; i++) { queue.push(node.children[i]); } } }; Tree.prototype.print = function() { if(!this.root) { return console.log('No root node found'); } let newline = new Node('|'); let queue = [this.root, newline]; let string = ''; while(queue.length) { let node = queue.shift(); string += node.data.toString() + ' '; if(node === newline && queue.length) { queue.push(newline); } for(let i = 0; i < node.children.length; i++) { queue.push(node.children[i]); } } console.log(string.slice(0, -2).trim()); }; Tree.prototype.printByLevel = function() { if(!this.root) { return console.log('No root node found'); } let newline = new Node('\n'); let queue = [this.root, newline]; let string = ''; while(queue.length) { let node = queue.shift(); string += node.data.toString() + (node.data !== '\n' ? ' ' : ''); if(node === newline && queue.length) { queue.push(newline); } for(let i = 0; i < node.children.length; i++) { queue.push(node.children[i]); } } console.log(string.trim()); }; let tree = new Tree(); tree.add('ceo'); tree.add('cto', 'ceo'); tree.add('dev1', 'cto'); tree.add('dev2', 'cto'); tree.add('dev3', 'cto'); tree.add('cfo', 'ceo'); tree.add('accountant', 'cfo'); tree.add('cmo', 'ceo'); tree.print(); // => ceo | cto cfo cmo | dev1 dev2 dev3 accountant tree.printByLevel(); // => ceo \n cto cfo cmo \n dev1 dev2 dev3 accountant console.log('tree contains dev1 is true:', tree.contains('dev1')); // => true console.log('tree contains dev4 is false:', tree.contains('dev4')); // => false console.log('--- BFS'); tree.traverseBFS(function(node) { console.log(node.data); }); // => ceo cto cfo cmo dev1 dev2 dev3 accountant console.log('--- DFS preOrder'); tree.traverseDFS(function(node) { console.log(node.data); }, 'preOrder'); // => ceo cto dev1 dev2 dev3 cfo accountant cmo console.log('--- DFS postOrder'); tree.traverseDFS(function(node) { console.log(node.data); }, 'postOrder'); // => dev1 dev2 dev3 cto accountant cfo cmo ceo tree.remove('cmo'); tree.print(); // => ceo | cto cfo | dev1 dev2 dev3 accountant tree.remove('cfo'); tree.print(); // => ceo | cto | dev1 dev2 dev3 The Graph Definition A Graph data structure consists of a finite (and possibly mutable) set of vertices or nodes or points, together with a set of unordered pairs of these vertices for an undirected Graph or a set of ordered pairs for a directed Graph. These pairs are known as edges, arcs, or lines for an undirected Graph and as arrows, directed edges, directed arcs, or directed lines for a directed Graph. The vertices may be part of the Graph structure, or may be external entities represented by integer indices or references. From Wikipedia A Graph data structure may also associate to each edge some edge value, such as a symbolic label or a numeric attribute (cost, capacity, length, etc.). Representation There are different ways of representing a graph, each of them with its own advantages and disadvantages. Here are the main 2: Adjacency list: For every vertex a list of adjacent vertices is stored. This can be viewed as storing the list of edges. This data structure allows the storage of additional data on the vertices and edges. Adjacency matrix: Data are stored in a two-dimensional matrix, in which the rows represent source vertices and columns represent destination vertices. The data on the edges and vertices must be stored externally. Complexity Adjacency list Storage Add Vertex Add Edge Query O( V + E Adjacency matrix Storage Add Vertex Add Edge Query O( V ^2) O( Graph The code//below uses the adjacency list representation. function Graph() { this.vertices = []; this.edges = []; this.numberOfEdges = 0; } Graph.prototype.addVertex = function(vertex) { this.vertices.push(vertex); this.edges[vertex] = []; }; Graph.prototype.removeVertex = function(vertex) { let index = this.vertices.indexOf(vertex); if(~index) { this.vertices.splice(index, 1); } while(this.edges[vertex].length) { let adjacentVertex = this.edges[vertex].pop(); this.removeEdge(adjacentVertex, vertex); } }; Graph.prototype.addEdge = function(vertex1, vertex2) { this.edges[vertex1].push(vertex2); this.edges[vertex2].push(vertex1); this.numberOfEdges++; }; Graph.prototype.removeEdge = function(vertex1, vertex2) { let index1 = this.edges[vertex1] ? this.edges[vertex1].indexOf(vertex2) : -1; let index2 = this.edges[vertex2] ? this.edges[vertex2].indexOf(vertex1) : -1; if(~index1) { this.edges[vertex1].splice(index1, 1); this.numberOfEdges--; } if(~index2) { this.edges[vertex2].splice(index2, 1); } }; Graph.prototype.size = function() { return this.vertices.length; }; Graph.prototype.relations = function() { return this.numberOfEdges; }; Graph.prototype.traverseDFS = function(vertex, fn) { if(!~this.vertices.indexOf(vertex)) { return console.log('Vertex not found'); } let visited = []; this._traverseDFS(vertex, visited, fn); }; Graph.prototype._traverseDFS = function(vertex, visited, fn) { visited[vertex] = true; if(this.edges[vertex] !== undefined) { fn(vertex); } for(let i = 0; i < this.edges[vertex].length; i++) { if(!visited[this.edges[vertex][i]]) { this._traverseDFS(this.edges[vertex][i], visited, fn); } } }; Graph.prototype.traverseBFS = function(vertex, fn) { if(!~this.vertices.indexOf(vertex)) { return console.log('Vertex not found'); } let queue = []; queue.push(vertex); let visited = []; visited[vertex] = true; while(queue.length) { vertex = queue.shift(); fn(vertex); for(let i = 0; i < this.edges[vertex].length; i++) { if(!visited[this.edges[vertex][i]]) { visited[this.edges[vertex][i]] = true; queue.push(this.edges[vertex][i]); } } } }; Graph.prototype.pathFromTo = function(vertexSource, vertexDestination) { if(!~this.vertices.indexOf(vertexSource)) { return console.log('Vertex not found'); } let queue = []; queue.push(vertexSource); let visited = []; visited[vertexSource] = true; let paths = []; while(queue.length) { let vertex = queue.shift(); for(let i = 0; i < this.edges[vertex].length; i++) { if(!visited[this.edges[vertex][i]]) { visited[this.edges[vertex][i]] = true; queue.push(this.edges[vertex][i]); // save paths between vertices paths[this.edges[vertex][i]] = vertex; } } } if(!visited[vertexDestination]) { return undefined; } let path = []; for(let j = vertexDestination; j != vertexSource; j = paths[j]) { path.push(j); } path.push(j); return path.reverse().join('-'); }; Graph.prototype.print = function() { console.log(this.vertices.map(function(vertex) { return (vertex + ' -> ' + this.edges[vertex].join(', ')).trim(); }, this).join(' | ')); }; ``` let graph = new Graph(); graph.addVertex(1); graph.addVertex(2); graph.addVertex(3); graph.addVertex(4); graph.addVertex(5); graph.addVertex(6); graph.print(); // 1 -> | 2 -> | 3 -> | 4 -> | 5 -> | 6 -> graph.addEdge(1, 2); graph.addEdge(1, 5); graph.addEdge(2, 3); graph.addEdge(2, 5); graph.addEdge(3, 4); graph.addEdge(4, 5); graph.addEdge(4, 6); graph.print(); // 1 -> 2, 5 | 2 -> 1, 3, 5 | 3 -> 2, 4 | 4 -> 3, 5, 6 | 5 -> 1, 2, 4 | 6 -> 4 console.log('graph size (number of vertices):', graph.size()); // => 6 console.log('graph relations (number of edges):', graph.relations()); // => 7 graph.traverseDFS(1, function(vertex) { console.log(vertex); }); // => 1 2 3 4 5 6 console.log('---'); graph.traverseBFS(1, function(vertex) { console.log(vertex); }); // => 1 2 5 3 4 6 graph.traverseDFS(0, function(vertex) { console.log(vertex); }); // => 'Vertex not found' graph.traverseBFS(0, function(vertex) { console.log(vertex); }); // => 'Vertex not found' console.log('path from 6 to 1:', graph.pathFromTo(6, 1)); // => 6-4-5-1 console.log('path from 3 to 5:', graph.pathFromTo(3, 5)); // => 3-2-5 graph.removeEdge(1, 2); graph.removeEdge(4, 5); graph.removeEdge(10, 11); console.log('graph relations (number of edges):', graph.relations()); // => 5 console.log('path from 6 to 1:', graph.pathFromTo(6, 1)); // => 6-4-3-2-5-1 graph.addEdge(1, 2); graph.addEdge(4, 5); console.log('graph relations (number of edges):', graph.relations()); // => 7 console.log('path from 6 to 1:', graph.pathFromTo(6, 1)); // => 6-4-5-1 graph.removeVertex(5); console.log('graph size (number of vertices):', graph.size()); // => 5 console.log('graph relations (number of edges):', graph.relations()); // => 4 console.log('path from 6 to 1:', graph.pathFromTo(6, 1)); // => 6-4-3-2-1
    https://bgoonz-blog.netlify.app/images/5.jpg
  • Web-Dev-Hub
    Video Chat Zumzi Instant Messenger
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    New Developers 1. Why are frameworks useful? Essentially the allure of these is the amount of time that is saved and the resulting efficiency in getting a project rolled out faster because there's a lot less of the initial work to be done. Frameworks take care of tasks like default browser settings, file structures, and layout templates for your website. This automation generates a uniform design for page elements like text, tables, forms, and buttons, amongst other things. Even complex navigation menus become standardized with frameworks as it can be consistently applied across your website with ease. 2. Types of framework There are many different kinds of this platform available for programmers. Typically, like a lot of things within this discipline can be split between frontend and backend development---first let's make the distinction between the two to help you understand the usefulness of these solutions. Backend frameworks These are designed to make the responsibility of interacting with the database an easier endeavor for the developer. It automates a lot of functions and processes that web developers use to record and retrieve user-inputted data. Frontend frameworks As the name suggests, these are very helpful on the presentation side of the website, creating a good foundation from which to build pages. These frameworks combine HTML, CSS, and Javascript to be really effective in creating conventions for various elements. Typically frontend web developers use them in conjunction with other effective tools. HTML conventions allow for standardization for elements like typography, while CSS conventions can help standardize positioning of elements in a grid-like system on the pages. This makes it easier for the developer to arrange and organize elements into a simple and uniform design across multiple displays and browsers. Javascript conventions offer the ability to style more advanced components like image carousels, lightboxes, button behaviors, and pop-ups. On another note, there are Javascript frameworks that focus on full application support---like AngularJS and Reactjs. Libraries of Javascript code like jQuery are also helpful in developing conventions that can be readily implemented in websites. To recap, the use of these tools helps the developer get up and running quickly without having to get bogged down with the initial hurdles that come with setting up a website. It creates uniform code across all pages of your website and presents a clean look for users. This in turn solves common issues like typography consistency and positioning difficulties on different pages. Best of all, frontend frameworks resolve any issues with browser compatibility and are key to responsive web design, which we'll discuss further on. Curious about a career in Web Development? Start learning for free! 3. Popular frameworks There are many of these tools that have become must-haves for beginner and expert web developers alike. As well as different languages, they focus on different directives and outcomes. One of the most popular frameworks is Bootstrap, which was originally developed by Twitter to maintain consistency in their interface development. It's very polished and efficient, and makes website development easier and faster. It has standardized conventions that are well recognized for HTML elements like buttons, alerts, forms, and typography. So popular that it's now known simply as "Rails," Ruby on Rails has revolutionised this language. As well as making it one of the easier programming languages to learn, Rails is particularly popular with beginners looking to code full-stack early on in their careers. Foundation was created from the Zurb style guide and much like Bootstrap, offers a complete solution for front-end design. Many large companies like Facebook, Yahoo, and Ebay utilize Foundation in their layouts. The framework encourages web developers to expand on the conventions and personalize them for developers' websites. Skeleton is a lighter example that doesn't come with all the bells and whistles that accompany the heavy-lifters like Bootstrap and Foundation. This encourages greater customization by only providing styling on the most basic and necessary elements. Developers who only need specific components to be styled utilize light-weight frameworks like Skeleton to achieve their goals. A simple Google search will turn up a lot of results for top tools being used and recommended. It's definitely beneficial to check out the different options and see which suits your development needs and design goals. 4. How do I use frameworks? Regardless of whether a developer uses a full frontend framework like Bootstrap or a lightweight option like Skeleton, these are efficient tools that should be seriously considered in every developer's process. Recognized frameworks offer more ease in collaboration as developers can access the same libraries for design conventions without having to resort to individual opinionated decisions. Additionally, there is support from the specific community with tutorials and articles on how to effectively use it. The ease of implementation and efficiency makes it almost a necessity to employ these tools in a web developer's process. Any time a programmer is finding themselves creating an ever-growing proprietary list of CSS rules, it's probably a good idea to look into using a framework to tidy things up. 5. What is a responsive framework? One of the best features of these systems is that they help create websites that are easily accessible and are able to be viewed across different browsers on different devices. A lot of frameworks accomplish this with dynamic code---utilizing classes that can be reused and formatted to take into consideration the device and/or browser that is being used. In other words, the layouts of webpages will change---certain elements will disappear and text will be smaller on smaller screens, while certain Javascript elements might not take effect at all. On larger screens, the extra real estate can be used to showcase higher quality images and more sophisticated design elements, as well as allowing for the white space beloved by web designers. In this current age when users are more likely to view websites on their mobile devices than their computers, it's important to have a mobile responsive website that creates an enriching user experience no matter what interface the user interacts with. In this video, our in-house web developer Abhi explains more about styling a mobile-responsive website with CSS: 6. Final thoughts Critics of frontend frameworks cite them as the source of a lot of cookie-cutter websites that are identical in appearance and interaction. This however, is an oversimplification. Why? Let's go back to the cooking example: a spatula is just a spatula---a lot of people have one and use the tool in the kitchen. But the food that is created will vary wildly across the spectrum, depending on the cook. In the same light, frontend frameworks are simply a tool that can be employed to create diverse and distinctive websites. Yes they're efficient, but it's up to the developer to make sure they're effective. If you want to learn some more about web development right now, these articles may interest you: A Guide To The Best Web Development Bootcamps And How To Choose One The Most In-Demand Web Developer Skills in 2021 5 Web Development Trends To Watch This Year
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Job Board Job Boards A curated list of awesome job boards. Table of Contents General Data Science Blockchain Design InfoSec Programming Remote Freelancer Other General LinkedIn Indeed Glassdoor Angel List arbeitnow 4 day week Data Science DataJobs.com Data Elixir AI Jobs Machine learning jobs Kaggle jobs icrunchdata KDnuggets Data Yoshi Opendatascience Jobs AnalyticsVidhya Jobs Jobs for New Data Scientists BigDataJobs StatsJobs Big Cloud Microprediction jobs Blockchain Blocktribe Crypto Jobs List CryptoJobs Blockew Cryptocurrency Jobs Design AIGA Authentic Jobs Behance Coroflot IXDA Dribble Krop Open Source Design Jobs UX Jobs Board Designer Jobs designmodo Design Jobs Board Design Week Jobs AIGA Design Jobs If You Could Jobs CreativeMornings Creativepool The Loop InfoSec NinjaJobs infosec-jobs CyberSecurityJobsite CareersinCyber CareersInfoSecurity CyberSecurityJobs YesWeHack Programming Carrots Goopensource.dev iOS Dev Jobs Elixir Jobs Front-End Developer Jobs Full-Stack Developer Jobs Functional Jobs Golangprojects we love golang Golang Forum Jobs Golang Job Board Golang Cafe Angular Jobs Angular Work Ember Job Board Vue.js Jobs Made with Vue.js Jobs React Jobs React Job Board We Love Angular We Work Meteor Drupal Jobs WordPress Jobs LaraJobs WPhired Python Job Board Pycoder's Jobs django gigs Django Jobs RubyNow Ruby on Rails Jobs Rust Programming Language Jobs WebAssembly Jobs JavaScript Jobs Jobs in JS R-users Remote Career Vault Remotebond Jobspresso We Work Remotely Workaline Remotive Remote remote | OK JustRemote SkipTheDrive remote.co remote4me.com Working Nomads EuropeRemotely AwesomeJobs Remote Python Ruby On Remote Remote ML JS Remotely Remote Arena letsworkremotely Workew wellpaid.io NODESK Remote Jobs FlexJobs RMTWRK remotify Remoters Jobmote Remotely Awesome Jobs DailyRemote Remote Developer Jobs Remotees Meerkad Work From Home Jobs Pangian Outsourcely ProsperCircle.org DynamiteJobs FlatWorld beefrii Hire Remote Freelancer Upwork Toptal Freelancer Guru People Per Hour Fiverr Hubstaff Outsource GigGrabbers CloudPeeps Local Solo YunoJuno Gun.io Other Monster GitHub Jobs Amazon Jobs HackerNews Jobs Stack Overflow Jobs Crunchboard Hacker Noon Jobs Jobbatical PowerToFly (Women) whoishiring.io SimplyHired CareerBuilder CareerCast Dice Techstars Product Hunt Jobs ZipRecruiter Idealist Aquent HackerX findwork.dev Livecareer The Muse LinkUp Authentic Jobs DevSnap Joblist.app Jobs2Careers JobisJob Joblift Adzuna TechMeAbroad HackerRank Jobs Find Bacon Codersrank jobbit subreddit Jora HNHIRING nocsok Y Combinator Job Board Relocate.me PRODUCTHIRE.NET Sports tech jobs#epicjobs Able StackShare Neuvoo Top Language Jobs Vanhack CalmJobs PeopleFirstJobs Naukri Digital Oxford Jobs CSS-Tricks Jobs Smashing Magazine Totaljobs XING Codepen Jobs The Guardian Jobs Jobs in Network snagajob Robert Half HigherEdJobs Mediabistro Joblist Workatastartup enviro f6s Ladders Cleverism VirtualVocations Mashable Jobvertise EqualOpportunity CNCF Job Board KDR Recruitment Diversify Tech Women Who Code Hitmarker Open GameDev Jobs Hey Gamer PRSA Job Center eFinancialCareers Uncubed Health eCareers TechFetch LaunchAfrica DiversityJobs ClearanceJobs IT Job Pro The-Dots CampaignJobs GoodJobs(Climate change, food insecurity) Tech Jobs for Good Entry Level Entry Level Jobs College Recruiter Internships Jr.DevJobs Graduateland TalentEgg entrylevel.io ErasmusIntern CareerRookie AfterCollege Startups Startup Jobs StartUpers WorkinStartups The Hub Unicorn Hunt StartupHire United States DallasJobs US Jobs Careerjet Nexxt National Labor Exchange Free & Open Source Free & Open Source Jobs Open Source Jobs LinuxJobs.io DevOps Jobs For DevOps Kube Careers Growth Hacking GrowthHackers
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Do & Don't of Interviewing! Do & Don't of Interviewing! Legend✅ = Do❌ = Don't⚠️ = Situational Before interview Things✅ Prepare pen, paper and earphones/headphones.✅ Find a quiet environment with good Internet connection.✅ Ensure webcam and audio are working. There were times I had to restart Chrome to get Hangouts to work again.✅ Request for the option to interview over Hangouts/Skype instead of a phone call; it is easier to send links or text across.✅ Decide on and be familiar with a programming language.✅ Familiarize yourself with the coding environment (CoderPad/CodePen). Set up the coding shortcuts, turn on autocompletion, tab spacing, etc.✅ Prepare answers to the frequently-asked behavioral questions in an interview.✅ Prepare some questions to ask at the end of the interview.✅ Dress comfortably. Usually you do not need to wear smart clothes, casual should be fine. T-shirts and jeans are acceptable at most places.✅ Stay calm and composed.⚠️ Turn off the webcam if possible. Most remote interviews will not require video chat and leaving it on only serves as a distraction. Introduction Things✅ Introduce yourself in a few sentences under a minute or two.✅ Mention interesting points that are relevant to the role you are applying for.✅ Sound enthusiastic! Speak with a smile and you will naturally sound more engaging.❌ Spend too long introducing yourself. The more time you spend talking the less time you have to code. Upon receiving the question Things✅ Repeat the question back at the interviewer.✅ Clarify any assumptions you made subconsciously. Many questions are under-specified on purpose. E.g. a tree-like diagram could very well be a graph that allows for cycles and a naive recursive solution would not work.✅ Clarify input format and range. Ask whether input can be assumed to be well-formed and non-null.✅ Work through a small example to ensure you understood the question.✅ Explain a high level approach even if it is a brute force one.✅ Improve upon the approach and optimize. Reduce duplicated work and cache repeated computations.✅ Think carefully, then state and explain the time and space complexity of your approaches.✅ If stuck, think about related problems you have seen before and how they were solved. Check out the tips in this section.❌ Ignore information given to you. Every piece is important.❌ Jump into coding straightaway.❌ Start coding without interviewer's green light.❌ Appear too unsure about your approach or analysis. Code out your solution Things✅ Explain what you are coding/typing to the interviewer, what you are trying to achieve.✅ Practice good coding style. Clear variable names, consistent operator spacing, proper indentation, etc.✅ Type/write at a reasonable speed. Too slow is no good.✅ As much as possible, write actual compilable code, not pseudocode.✅ Write in a modular fashion. Extract out chunks of repeated code into functions.✅ Ask for permission to use trivial functions without having to implement them; saves you some time.✅ Use the hints given by the interviewer.✅ Demonstrate mastery of your chosen programming language.✅ Demonstrate technical knowledge in data structures and algorithms.✅ If you are cutting corners in your code, state that out loud to your interviewer and say what you would do in a non-interview setting (no time constraints). E.g., "Under non-interview settings, I would write a regex to parse this string rather than using split() which may not cover all cases."✅ Practice whiteboard space-management skills.⚠️ Reasonable defensive coding. Check for nulls, empty collections, etc. Can omit if input validity has been clarified with the interviewer.❌ Remain quiet the whole time while coding.❌ Spend too much time writing comments.❌ Use extremely verbose or single-character (unless they're common like i, n) variable names.❌ Copy and paste code without checking (e.g. variables need to be renamed).❌ Interrupt your interviewer when they are talking. Usually if they speak, they are trying to give you hints or steer you in the right direction.❌ Write too big (takes up too much space) or too small (illegible) if on a whiteboard. After coding Things✅ Scan through your code for mistakes as if it was your first time seeing code written by someone else.✅ Check for off-by-one errors.✅ Come up with test cases. Try extreme test cases - empty sets, single item sets, negative numbers✅ Step through your code with those test cases.✅ Look out for places where you can refactor.✅ Reiterate the time and space complexity of your code.✅ Explain trade-offs and how the code/approach can be improved if given more time.❌ Immediately announce that you are done coding. Do the above first!❌ Argue with the interviewer. They may be wrong but that is very unlikely given that they are familiar with the question. Wrap up Things✅ Ask questions. More importantly, ask good and engaging questions that are tailored to the company! Pick some questions from this list.✅ Thank the interviewer.⚠️ Ask about your interview performance. It can get awkward.❌ End the interview without asking any questions. Post interview Things✅ Record the interview questions and answers down as these can be useful for future reference.⚠️ Send a follow up email to your interviewer(s) thanking them for their time and the opportunity to interview with them.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Developer Interview Questions Table of Contents Programming Languages/Frameworks/Platforms Android AngularJS Angular BackboneJS C++ C C♯.NET Clojure CSS Cucumber Django Docker EmberJS Erlang Golang GraphQl HTML Ionic iOS Java JavaScript jQuery Front-end build tools KnockoutJS Less Lisp NodeJS Objective-C PHP Python ReactJS Rails Ruby Rust Sass Scala Shell Spark Swift Vue.js Wordpress TypeScript Database technologies Cassandra Microsoft Access MongoDB MySQL Neo4j Oracle Postgres SQL SQL Lite Caching technologies Memcached Redis OS Linux Windows Algorithms Blockchain Coding exercises Comprehensive lists Design patterns Data structures Networks Security Data Science Programming Languages/Frameworks/Platforms Android 10 Android interview question answers for Freshers 20 Essential Android Interview Questions from Toptal 25 Essential Android Interview Questions from Adeva A couple of Android questions posted by Quora users A great list of Android interview questions covering all the aspects of this career Collection of Android and Java related questions and topics, including general developer questions, Java core, Data structures, Build Tools, Programming Paradigms, Core Android, Databases and etc Collection of Android and Java questions divided by experience Android Interview Questions & How to Interview Candidates RocketSkill App Android Interview Questions Android cheat sheet: Coding program, Data structure, Android and Java interview questions with answers and categorized by topics Android Interview Questions And Answers From Beginner To Advanced Interview Questions for Senior Android Developers 35+ Android Interview Questions AngularJS 12 Essential AngularJS Interview Questions from Toptal An AngularJS exam with questions from beginner to expert by @gdi2290 from @AngularClass 29 AngularJS Interview Questions – Can You Answer Them All? Great Article from Codementor AngularJS interview questions and answers for experienced developers AngularJS Interview Questions which have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of AngularJS This article discusses the top 50 Most occurred AngularJS interview question with answers Top 25 Angularjs Interview Questions and Quiz 100 AngularJS Interview Questions - Quick Refresher Angular A list of helpful Angular related questions you can use to interview potential candidates, test yourself or completely ignore Angular 2 Interview Questions List of 300 Angular Interview Questions and Answers Angular Interview Questions (2020) BackboneJS 8 Essential Backbonejs Interview Questions from Toptal Backbonejs Interview Questions And Answers from web technology experts notes Top 25 Backbone.js interview questions C++ 1000+ Multiple Choice Questions & Answers in C++ with explanations 200 C++ interview questions and answers 24 Essential C++ Interview Questions from Toptal C++ Interview Questions and Answers for Freshers and Experienced developers C++ Interview Questions from GeekInterview C++ Programming Q&A and quizzes from computer science portal for geeks C++ Programming Questions and Answers related to such topics as OOPs concepts, Object and Classes, Functions, Constructors and Destructors, Inheritance and etc LeetCode Problems' Solutions written in C++ 25 Fundamental C++ Interview Questions C Basic C language technical frequently asked interview questions and answers It includes data structures, pointers interview questions and answers for experienced C Programming Interview Questions and Answers for such topics as Bits and Bytes, Preprocessors, Functions, Strings, Language basics and etc C Programming Interview Questions have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of C Programming First set of commonly asked C programming interview questions from computer science portal for geeks Second set of commonly asked C programming interview questions from computer science portal for geeks 9 Essential C Interview Questions with answers Top C Interview Questions and Answers C 15 Essential C# Interview Question from Toptal C# interview questions from dotnetfunda.com Top 100 C# Interview Questions and Answers Top 50 C# Interview Questions & Answers 50 C# Coding Interview Questions and Answers 20 C# OOPS Interview Questions and Answers 30+ C# Interview Questions.NET 300 ASPNET interview questions and answers ASP.NET Core Interview Questions Great list of NET interview questions covering all the NET platform topics NET Interview Questions and Answers for Beginners which consists of the most frequently asked questions in NET This list of 100+ questions and answers gauge your familiarity with the NET platform Questions gathered by community of the StackOverflow What Great NET Developers Ought To Know (More NET Interview Questions) Clojure Classic 'Fizz Buzz' interview question for Clojure developers Clojure Interview Questions for experienced devs Coding exercises in Clojure, handy practice for technical interview questions Experience and questions from Clojure developer interview collected by Reddit users Interview cake Clojure solutions CSS CSS interview questions and answers for freshers and experienced candidates Also there you can find CSS online practice tests to fight written tests and certification exams on CSS Development hiring managers and potential interviewees may find there sample CSS proficiency interview Q&As and code snippets useful Interview Questions and Exercises About CSS Top 50 CSS(Cascading Style Sheet) Interview Questions covering the most of tricky CSS moments CSS Questions and Answers Cucumber Cucumber Web Application BDD Sample Interview Questions Guide to building a simple Cucumber + Watir page object pattern framework Django Some abstract interview questions for Python/Django developers Some Django basic interview questions to establish the basic level of the candidates Top 16 Django Interview Questions for both freshers and experienced developers Docker Docker Interview Questions Top Docker Interview Questions You Must Prepare In 2019 Top Docker Interview Questions And Answers DOCKER (SOFTWARE) INTERVIEW QUESTIONS & ANSWERS 30 Docker Interview Questions and Answers in 2019 Docker Interview Questions & Answers Top 50 Docker Interview Questions & Answers EmberJS 8 Essential Emberjs Interview Questions from Toptal Top 25 Emberjs Interview Questions for both freshers and experienced developers Erlang Top 22 Erlang Interview Questions for both freshers and experienced developers Golang Solutions for Elements of Programming Interviews problems written in Golang Solutions for some basic coding interview tasks written in Go Top 20 GO Programming Interview Questions for both freshers and experienced developers GraphQl 8 GraphQl Interview Questions To Know How to GraphQl - Common Questions HTML 10 Typical HTML Interview Exercises from SitePoint.com 16 Essential HTML5 Interview Questions from Toptal 40 important HTML 5 Interview questions with answers HTML interview questions and answers for freshers and experienced candidates Also find HTML online practice tests to fight written tests and certification exams on HTML Top 50 HTML Interview Questions for both freshers and experienced developers Common HTML interview questions for freshers HTML Questions and Answers 30 HTML Interview Questions and Answers 30+ HTML Interview Questions (2021) Ionic 23 Beginner Level Ionic Framework Questions 12 Essential Ionic Interview Questions 45 Ionic Interview Questions Most Asked Ionic Interview Questions iOS 14 Essential iOS Interview Questions from Toptal 20 iOS Developer Interview Questions and Answers for getting you ready for your interview 25 Essential iOS Interview Questions from Adeva A small guide to help those looking to hire a developer or designer for iOS work While tailored for iOS, many questions could be used for Android developers or designers as well A great self-test if you're looking to keep current or practice for your own interview All you need to know about iOS technical interview including some tips for preparing, questions and some coding exercises Interview Questions for iOS and Mac Developers from the CEO of Black Pixel iOS Interview Questions and Answers including such topics as Development Basics, App states and multitasking, App states, Core app objects iOS Interview Questions For Senior Developers 50 iOS Interview Questions And Answers 1 50 iOS Interview Questions And Answers Part 2 50 iOS Interview Questions And Answers Part 3 50 iOS Interview Questions And Answers Part 4 50 iOS Interview Questions And Answers Part 5 10 iOS interview questions and answers iOS Developer and Designer Interview Questions IOS Interview Questions and Answers iOS Interview Questions For Beginners Babylon iOS Interview Questions RocketSkill App iOS Interview Questions iOS Static vs Dynamic Dispatch Java List of Java programs for interview Categoriwise 115 Java Interview Questions and Answers – The ULTIMATE List 37 Java Interview Questions to Practice With from Codementor 21 Essential Java Interview Questions Top 30 Core Java Interview Questions 29 Essential Java Interview Questions from Adeva A collection of Java interview questions and answers to them Data Structures and Algorithms in Java which can be useful in interview process Java Interview Questions: How to crack the TOP 15 questions 300 Core Java Interview Questions Top 10 Tricky Java interview questions and Answers Top 25 Most Frequently Asked Interview Core Java Interview Questions And Answers Top 40 Core Java Interview Questions Answers from Telephonic Round Top 50 Spring Interview Questions You Must Prepare For In 2020 Spring Interview Questions And Answers Interview Cake Java Interview Questions Java Interview Questions & Quizzes Essetial Java Interview Questions Fundamental Java Interview Questions JavaScript Practice common algorithms using JavaScript 10 Interview Questions Every JavaScript Developer Should Know 21 Essential JavaScript Interview Questions from best mentors all over the world 20 Essential JavaScript Interview Questions from Adeva 37 Essential JavaScript Interview Questions from Toptal 5 More JavaScript Interview Exercises 5 Typical JavaScript Interview Exercises Development hiring managers and potential interviewees may find these sample JavaScript proficiency interview Q&As and code snippets useful 123 Essential JavaScript Interview Question JavaScript Interview Questions have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of JavaScript JS: Basics and Tricky Questions JS: Interview Algorithm Some basic javascript coding challenges and interview questions Some JavaScript interview exercises Ten Questions I've Been Asked, Most More Than Once, Over Six Technical JavaScript / Front-End Engineer Job Interviews. Top 85 JavaScript Interview Questions Interview Cake JavaScript Interview Questions The Best Frontend JavaScript Interview Questions (written by a Frontend Engineer) 10 JavaScript Concepts You Need to Know for Interviews Front end interview handbook JavaScript Interview Questions - Quick Refresher The MEGA Interview Guide Javascript Interview Questions and Answers (2020) JavaScript Modern Interview Code Challenges 2021 70 JavaScript Interview Questions jQuery Top 50 jquery interview questions 17 Essential jQuery Interview Questions From Toptal Front-end build tools Webpack interview questions & answers Gulp js interview questions Grunt js interview questions for beginners Grunt js interview questions KnockoutJS 15 interview questions from CodeSample.com 20 questions you might be asked about KnockoutJS in an interview for both freshers and experienced developers Less Top 25 LESS Interview Questions Lisp 10 LISP Questions & Answers Top 18 Lisp Interview Questions from Career Guru NodeJS 25 Essential Node.js Interview Questions from Adeva 8 Essential Nodejs Interview Questions from Toptal Node.JS Interview Questions have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of Node.JS Node.js Interview Questions and Answers Top 25 Nodejs Interview Questions & Answers from Career Guru Top 30 Node.Js Interview Questions With Answers Top Nodejs Interview Questions & Answers Node.js Interview Questions in Chinese Objective-C Interview Qs for Objective-C and Swift iOS Interview Questions For Beginners PHP 100 PHP interview questions and answers from CareerRide.com 21 Essential PHP Interview Questions from Toptal 20 Common PHP Job Interview Questions and Answers 25 Essential PHP Interview Questions from Adeva PHP interview questions and answers for freshers Top 100 PHP Interview Questions & Answers from CareerGuru 25 PHP Interview Questions 26 Essential PHP Interview Questions for 2018 Cracking PHP Interviews Questions ebook 300+ Q&A PHP Interview Questions - Quick Refresher 30+ PHP Interview Questions Python 26 Essential Python Interview Questions from Adeva 20 Python interview questions and answers 11 Essential Python Interview Questions from Toptal A listing of questions that could potentially be asked for a python job listing Interview Questions for both beginners and experts Interview Cake Python Interview Questions Python Frequently Asked Questions (Programming) Python interview questions collected by Reddit users Top 25 Python Interview Questions from Career Guru Python Interview 10 questions from Corey Schafer Python interview questions. Part I. Junior Python interview questions. Part II. Middle Python interview questions. Part III. Senior Python Interview Questions and Answers (2019) 100 Python Interview Questions - Quick Refresher Top 100 Python Interview Questions from Edureka (2021) Ruby on Rails 20 Ruby on Rails interview questions and answers from CareerRide.com 9 Essential Ruby on Rails Interview Questions from Toptal High-level Ruby on Rails Interview Questions Ruby And Ruby On Rails interview Q&A Some of the most frequently asked Ruby on Rails questions and how to answer them confidently 11 Ruby on Rails Interview Practice Questions Top 53 Ruby on Rails Interview Questions & Answers 10 Ruby on Rails interview questions and answers ReactJS Reddit users share their expectations from ReactJS interview This is a first in the series of interview questions related to ReactJS This quiz intends to test your understanding of ReactJS fundamentals (Set 3) This quiz intends to test your understanding of ReactJS fundamentals 5 Essential React.js Interview Questions React Interview Questions Toptal's 21 Essential React.js Interview Questions 19 Essential ReactJs Interview Questions Ruby 21 Essential Ruby Interview Questions from Toptal 15 Questions to Ask During a Ruby Interview A list of questions about Ruby programming you can use to quiz yourself The Art of Ruby Technical Interview Interview Cake Ruby Interview Questions Frequently Asked Ruby Interview Questions Rust Top 250+ Rust Programming Language Interview Questions Rust Programming Interview Questions and Answers rust-exam: A set of questions about the Rust programming language Best Rust Programming Language Interview Questions and answers Sass Top 17 Sass Interview Questions from Career Guru Top 10 Sass Interview Questions from educba Scala 4 Interview Questions for Scala Developers A list of Frequently Asked Questions and their answers, sorted by category A list of helpful Scala related questions you can use to interview potential candidates How Scala Developers Are Being Interviewed Top 25 Scala Interview Questions & Answers from Toptal SharePoint Sharepoint Interview Question For Developer Top SharePoint Interview Questions and Answers Shell Top 50 Shell Scripting Interview Questions from Career Guru Spark Carefully Curated 70 Spark Questions with Additional Optimization Guides (First in the series) Swift 10 Essential Swift Interview Questions from Toptal Get prepared for your next iOS job interview by studying high quality LeetCode solutions in Swift 5 Swift Interview Questions and Answers Swift Programming Language Interview Questions And Answers from mycodetips.com Your top 10 Swift questions answered Swift interview questions and answers on Swift 5 by Raywenderlich Dynamic keyword in Swift Vue.js List of 300 VueJS Interview Questions WordPress Top 45 WordPress interview questions 10 Essential WordPress Interview Questions TypeScript Typescript Interview Questions Top 10 TypeScript Interview Questions and Answers for Beginner Web Developers 2019 Database technologies Cassandra Top 23 Cassandra Interview Questions from Career Guru Microsoft Access Top 16 Microsoft Access Database Interview Questions from Career Guru MongoDB 28 MongoDB NoSQL Database Interview Questions and Answers MongoDB frequently Asked Questions by expert members with experience in MongoDB These questions and answers will help you strengthen your technical skills, prepare for the new job test and quickly revise the concepts MongoDB Interview Questions from JavaTPointcom MongoDB Interview Questions that have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of MongoDB Top 20 MongoDB interview questions from Career Guru MySQL 10 MySQL Database Interview Questions for Beginners and Intermediates 100 MySQL interview questions 15 Basic MySQL Interview Questions for Database Administrators 28 MySQL interview questions from JavaTPoint.com 40 Basic MySQL Interview Questions with Answers Top 50 MySQL Interview Questions & Answers from Career Guru Neo4j Top 20 Neo4j Interview Questions from Career Guru Oracle General Oracle Interview Questions & Answers Postgres 13 PostgreSQL Interview Q&A Frequently Asked Basic PostgreSQL Interview Questions and Answers PostgreSQL Interview Preparation Guide PostgreSQL Interview Q&A from CoolInterview.com SQL 10 Frequently asked SQL Query Interview Questions 45 Essential SQL Interview Questions from Toptal Common Interview Questions and Answers General Interview Questions and Answers Schema, Questions & Solutions for SQL Exercising SQL Interview Questions that have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of SQL SQL Interview Questions CHEAT SHEET SQLite Top 20 SQLITE Interview Questions from Career Guru Caching technologies Memcached Memcached Interview Questions from Javapoint Memcached Interview Questions from Wisdomjobs Redis Redis Interview Questions from Javapoint Redis Interview Questions from Wisdomjobs Redis Interview Questions from Career Guru OS Linux 10 Job Interview Questions for Linux System Administrators from Linux.com 10 Useful Random Linux Interview Questions and Answers 11 Basic Linux Interview Questions and Answers 11 Essential Linux Interview Questions from Toptal Top 30 Linux System Admin Interview Questions & Answers Top 50 Linux Interview Questions from Career Guru 278 Test Questions and Answers for *nix System Administrators Linux Interview Questions - Quick Refresher Windows Top 10 Interview Questions for Windows Administrators Top 22 Windows Server Interview Questions from Career Guru Windows Admin Interview Questions & Answers DevOps Linux System Administrator/DevOps Interview Questions Top DevOps Interview Questions You Must Prepare In 2021 Top 60+ DevOps Interview Questions & Answers in 2021 DevOps Interview Questions & Answers Algorithms Comprehensive list of interview questions of top tech companies A great list of Java interview questions Algorithms playground for common interview questions written in Ruby EKAlgorithms contains some well known CS algorithms & data structures Top 10 Algorithms for Coding Interview Top 15 Data Structures and Algorithm Interview Questions for Java programmer Top Algorithms Questions by Topics Daily Coding Interview Practice Blockchain Top 55 Blockchain Interview Questions You Must Prepare In 2018 Blockchain Interview Questions Top Blockchain Interview Questions Blockchain Developer Interview Questions and Answers 10 Essential Blockchain Interview Questions Top 30 Blockchain Interview Questions – For Freshers to Experienced Most Frequently Asked Blockchain Interview Questions Coding exercises Common interview questions and puzzles solved in several languages Interactive, test-driven Python coding challenges (algorithms and data structures) typically found in coding interviews or coding competitions Interview questions solved in python 7 Swift Coding Challenges to Practice Your Skills Comprehensive lists A list of helpful front-end related questions you can use to interview potential candidates, test yourself or completely ignore Front End Developer Interview Questions Answers to Front End Developer Interview Questions Some simple questions to interview potential backend candidates Design Patterns Design Pattern Interview Questions that have been designed specially to get you acquainted with the nature of questions you may encounter during your interview for the subject of Design Pattern Design Patterns for Humans™ - An ultra-simplified explanation Design Patterns implemented in Java Design Patterns implemented in DotNet Data structures Top 15 Data Structures and Algorithm Interview Questions for Java programmer Top 50 Data Structure Interview Questions from Career Guru What is Data Structure? | Top 40 Data Structure Interview Questions Networks Top 100 Networking Interview Questions & Answers from Career Guru Networking Interview Questions Security 101 IT Security Interview Questions How to prepare for an information security job interview? Information Security Interview Questions from Daniel Miessler Top 50 Information Security Interview Questions for freshers and experts Security Interview Questions (and Answers) from Matthew Adeline Data Science Data Science Interview Questions for Top Tech Companies 66 Job Interview Questions for Data Scientists Top 45 Data Science Interview Questions You Must Prepare In 2021 Top 30 data science interview questions Top 100 Data science interview questions Data Science Interview Questions 160+ Data Science Interview Questions
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Web Apis Web Audio Api Basic concepts behind Web Audio API This article explains some of the audio theory behind how the features of the Web Audio API work, to help you make informed decisions while designing how audio is routed through your app. It won't turn you into a master sound engineer, but it will give you enough background to understand why the Web Audio API works like it does. Audio graphs The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources --- with different types of channel layout --- are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects. Audio nodes are linked via their inputs and outputs, forming a chain that starts with one or more sources, goes through one or more nodes, then ends up at a destination. Although, you don't have to provide a destination if you, say, just want to visualize some audio data. A simple, typical workflow for web audio would look something like this: Create the audio context. Inside the context, create sources --- such as <audio>, oscillator, or stream. Create effects nodes, such as reverb, biquad filter, panner, or compressor. Choose the final destination for the audio, such as the user's computer speakers. Establish connections from the audio sources through zero or more effects, eventually ending at the chosen destination. Note: The number of audio channels available on a signal is frequently presented in a numeric format, such as 2.0 or 5.1. This is called channel notation. The first number is the number of full frequency range audio channels that the signal includes. The number after the period indicates the number of those channels which are reserved for low-frequency effect (LFE) outputs; these are often referred to as subwoofers. Each input or output is composed of one or more audio channels, which together represent a specific audio layout. Any discrete channel structure is supported, including mono, stereo, quad, 5.1, and so on. Audio sources can be obtained in a number of ways: Sound can be generated directly in JavaScript by an audio node (such as an oscillator). Created from raw PCM data (the audio context has methods to decode supported audio formats). Taken from HTML media elements (such as <video> or <audio>). Taken directly from a WebRTC MediaStream (such as a webcam or microphone). Audio data: what's in a sample When an audio signal is processed, sampling means the conversion of a continuous signal to a discrete signal; or put another way, a continuous sound wave, such as a band playing live, is converted to a sequence of samples (a discrete-time signal) that allow a computer to handle the audio in distinct blocks. A lot more information can be found on the Wikipedia page Sampling (signal processing). Audio buffers: frames, samples and channels An AudioBuffer takes as its parameters a number of channels (1 for mono, 2 for stereo, etc), a length, meaning the number of sample frames inside the buffer, and a sample rate, which is the number of sample frames played per second. A sample is a single float32 value that represents the value of the audio stream at each specific point in time, in a specific channel (left or right, if in the case of stereo). A frame, or sample frame, is the set of all values for all channels that will play at a specific point in time: all the samples of all the channels that play at the same time (two for a stereo sound, six for 5.1, etc.) The sample rate is the number of those samples (or frames, since all samples of a frame play at the same time) that will play in one second, measured in Hz. The higher the sample rate, the better the sound quality. Let's look at a Mono and a Stereo audio buffer, each is one second long, and playing at 44100Hz: The Mono buffer will have 44100 samples, and 44100 frames. The length property will be 44100. The Stereo buffer will have 88200 samples, but still 44100 frames. The length property will still be 44100 since it's equal to the number of frames. When a buffer plays, you will hear the left most sample frame, and then the one right next to it, etc. In the case of stereo, you will hear both channels at the same time. Sample frames are very useful, because they are independent of the number of channels, and represent time, in a useful way for doing precise audio manipulation. Note: To get a time in seconds from a frame count, divide the number of frames by the sample rate. To get a number of frames from a number of samples, divide by the channel count. Here's a couple of simple examples: var context = new AudioContext(); var buffer = context.createBuffer(2, 22050, 44100); Note: In digital audio, 44,100 Hz (alternately represented as 44.1 kHz) is a common sampling frequency. Why 44.1kHz? Firstly, because the hearing range of human ears is roughly 20 Hz to 20,000 Hz. Via the Nyquist--Shannon sampling theorem, the sampling frequency must be greater than twice the maximum frequency one wishes to reproduce. Therefore, the sampling rate has to be greater than 40 kHz. Secondly, signals must be low-pass filtered before sampling, otherwise aliasing occurs. While an ideal low-pass filter would perfectly pass frequencies below 20 kHz (without attenuating them) and perfectly cut off frequencies above 20 kHz, in practice a transition band is necessary, where frequencies are partly attenuated. The wider this transition band is, the easier and more economical it is to make an anti-aliasing filter. The 44.1 kHz sampling frequency allows for a 2.05 kHz transition band. If you use this call above, you will get a stereo buffer with two channels, that when played back on an AudioContext running at 44100Hz (very common, most normal sound cards run at this rate), will last for 0.5 seconds: 22050 frames/44100Hz = 0.5 seconds. var context = new AudioContext(); var buffer = context.createBuffer(1, 22050, 22050); If you use this call, you will get a mono buffer with just one channel), that when played back on an AudioContext running at 44100Hz, will be automatically resampled to 44100Hz (and therefore yield 44100 frames), and last for 1.0 second: 44100 frames/44100Hz = 1 second. Note: Audio resampling is very similar to image resizing. Say you've got a 16 x 16 image, but you want it to fill a 32x32 area. You resize (or resample) it. The result has less quality (it can be blurry or edgy, depending on the resizing algorithm), but it works, with the resized image taking up less space. Resampled audio is exactly the same: you save space, but in practice you will be unable to properly reproduce high frequency content, or treble sound. Planar versus interleaved buffers The Web Audio API uses a planar buffer format. The left and right channels are stored like this: LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR (for a buffer of 16 frames) This is very common in audio processing: it makes it easy to process each channel independently. The alternative is to use an interleaved buffer format: LRLRLRLRLRLRLRLRLRLRLRLRLRLRLRLR (for a buffer of 16 frames) This format is very common for storing and playing back audio without much processing, for example a decoded MP3 stream. The Web Audio API exposes only planar buffers, because it's made for processing. It works with planar, but converts the audio to interleaved when it is sent to the sound card for playback. Conversely, when an MP3 is decoded, it starts off in interleaved format, but is converted to planar for processing. Audio channels Different audio buffers contain different numbers of channels: from the more basic mono (only one channel) and stereo (left and right channels), to more complex sets like quad and 5.1, which have different sound samples contained in each channel, leading to a richer sound experience. The channels are usually represented by standard abbreviations detailed in the table below: Name Channels Mono 0: M: mono Stereo 0: L: left 1: R: right Quad 0: L: left 1: R: right 2: SL: surround left 3: SR: surround right 5.1 0: L: left 1: R: right 2: C: center 3: LFE: subwoofer 4: SL: surround left 5: SR: surround right Up-mixing and down-mixing When the number of channels doesn't match between an input and an output, up- or down-mixing happens according the following rules. This can be somewhat controlled by setting the AudioNode.channelInterpretation property to speakers or discrete: Web Audio API The Web Audio API provides a powerful and versatile system for controlling audio on the Web, allowing developers to choose audio sources, add effects to audio, create audio visualizations, apply spatial effects (such as panning) and much more. Web audio concepts and usage The Web Audio API involves handling audio operations inside an audio context, and has been designed to allow modular routing. Basic audio operations are performed with audio nodes, which are linked together to form an audio routing graph. Several sources --- with different types of channel layout --- are supported even within a single context. This modular design provides the flexibility to create complex audio functions with dynamic effects. Audio nodes are linked into chains and simple webs by their inputs and outputs. They typically start with one or more sources. Sources provide arrays of sound intensities (samples) at very small timeslices, often tens of thousands of them per second. These could be either computed mathematically (such as OscillatorNode), or they can be recordings from sound/video files (like AudioBufferSourceNode and MediaElementAudioSourceNode) and audio streams ( MediaStreamAudioSourceNode). In fact, sound files are just recordings of sound intensities themselves, which come in from microphones or electric instruments, and get mixed down into a single, complicated wave. Outputs of these nodes could be linked to inputs of others, which mix or modify these streams of sound samples into different streams. A common modification is multiplying the samples by a value to make them louder or quieter (as is the case with GainNode). Once the sound has been sufficiently processed for the intended effect, it can be linked to the input of a destination ( BaseAudioContext.destination), which sends the sound to the speakers or headphones. This last connection is only necessary if the user is supposed to hear the audio. A simple, typical workflow for web audio would look something like this: Create audio context Inside the context, create sources --- such as <audio>, oscillator, stream Create effects nodes, such as reverb, biquad filter, panner, compressor Choose final destination of audio, for example your system speakers Connect the sources up to the effects, and the effects to the destination. Timing is controlled with high precision and low latency, allowing developers to write code that responds accurately to events and is able to target specific samples, even at a high sample rate. So applications such as drum machines and sequencers are well within reach. The Web Audio API also allows us to control how audio is spatialized. Using a system based on a source-listener model, it allows control of the panning model and deals with distance-induced attenuation induced by a moving source (or moving listener). Note: You can read about the theory of the Web Audio API in a lot more detail in our article Basic concepts behind Web Audio API. Web Audio API target audience The Web Audio API can seem intimidating to those that aren't familiar with audio or music terms, and as it incorporates a great deal of functionality it can prove difficult to get started if you are a developer. It can be used to incorporate audio into your website or application, by providing atmosphere like futurelibrary.no, or auditory feedback on forms. However, it can also be used to create advanced interactive instruments. With that in mind, it is suitable for both developers and musicians alike. We have a simple introductory tutorial for those that are familiar with programming but need a good introduction to some of the terms and structure of the API. There's also a Basic Concepts Behind Web Audio API article, to help you understand the way digital audio works, specifically in the realm of the API. This also includes a good introduction to some of the concepts the API is built upon. Learning coding is like playing cards --- you learn the rules, then you play, then you go back and learn the rules again, then you play again. So if some of the theory doesn't quite fit after the first tutorial and article, there's an advanced tutorial which extends the first one to help you practice what you've learnt, and apply some more advanced techniques to build up a step sequencer. We also have other tutorials and comprehensive reference material available that covers all features of the API. See the sidebar on this page for more. If you are more familiar with the musical side of things, are familiar with music theory concepts, want to start building instruments, then you can go ahead and start building things with the advanced tutorial and others as a guide (the above-linked tutorial covers scheduling notes, creating bespoke oscillators and envelopes, as well as an LFO among other things.) If you aren't familiar with the programming basics, you might want to consult some beginner's JavaScript tutorials first and then come back here --- see our Beginner's JavaScript learning module for a great place to begin. Web Audio API interfaces The Web Audio API has a number of interfaces and associated events, which we have split up into nine categories of functionality. General audio graph definition General containers and definitions that shape audio graphs in Web Audio API usage. AudioContext The AudioContext interface represents an audio-processing graph built from audio modules linked together, each represented by an AudioNode. An audio context controls the creation of the nodes it contains and the execution of the audio processing, or decoding. You need to create an AudioContext before you do anything else, as everything happens inside a context. AudioNode The AudioNode interface represents an audio-processing module like an audio source (e.g. an HTML <audio> or <video> element), audio destination, intermediate processing module (e.g. a filter like BiquadFilterNode, or volume control like GainNode). AudioParam The AudioParam interface represents an audio-related parameter, like one of an AudioNode. It can be set to a specific value or a change in value, and can be scheduled to happen at a specific time and following a specific pattern. AudioParamMap Provides a maplike interface to a group of AudioParam interfaces, which means it provides the methods forEach(), get(), has(), keys(), and values(), as well as a size property. BaseAudioContext The BaseAudioContext interface acts as a base definition for online and offline audio-processing graphs, as represented by AudioContext and OfflineAudioContext respectively. You wouldn't use BaseAudioContext directly --- you'd use its features via one of these two inheriting interfaces. The [ended](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/ended_event "/en-US/docs/Web/Events/ended") event The ended event is fired when playback has stopped because the end of the media was reached. Defining audio sources Interfaces that define audio sources for use in the Web Audio API. AudioScheduledSourceNode The AudioScheduledSourceNode is a parent interface for several types of audio source node interfaces. It is an AudioNode. OscillatorNode The OscillatorNode interface represents a periodic waveform, such as a sine or triangle wave. It is an AudioNode audio-processing module that causes a given frequency of wave to be created. AudioBuffer The AudioBuffer interface represents a short audio asset residing in memory, created from an audio file using the BaseAudioContext.decodeAudioData method, or created with raw data using BaseAudioContext.createBuffer. Once decoded into this form, the audio can then be put into an AudioBufferSourceNode. AudioBufferSourceNode The AudioBufferSourceNode interface represents an audio source consisting of in-memory audio data, stored in an AudioBuffer. It is an AudioNode that acts as an audio source. MediaElementAudioSourceNode The MediaElementAudioSourceNode interface represents an audio source consisting of an HTML5 <audio> or <video> element. It is an AudioNode that acts as an audio source. MediaStreamAudioSourceNode The MediaStreamAudioSourceNode interface represents an audio source consisting of a MediaStream (such as a webcam, microphone, or a stream being sent from a remote computer). If multiple audio tracks are present on the stream, the track whose id comes first lexicographically (alphabetically) is used. It is an AudioNode that acts as an audio source. MediaStreamTrackAudioSourceNode A node of type MediaStreamTrackAudioSourceNode represents an audio source whose data comes from a MediaStreamTrack. When creating the node using the createMediaStreamTrackSource() method to create the node, you specify which track to use. This provides more control than MediaStreamAudioSourceNode. Defining audio effects filters Interfaces for defining effects that you want to apply to your audio sources. BiquadFilterNode The BiquadFilterNode interface represents a simple low-order filter. It is an AudioNode that can represent different kinds of filters, tone control devices, or graphic equalizers. A BiquadFilterNode always has exactly one input and one output. ConvolverNode The ConvolverNode interface is an AudioNode that performs a Linear Convolution on a given AudioBuffer, and is often used to achieve a reverb effect. DelayNode The DelayNode interface represents a delay-line; an AudioNode audio-processing module that causes a delay between the arrival of an input data and its propagation to the output. DynamicsCompressorNode The DynamicsCompressorNode interface provides a compression effect, which lowers the volume of the loudest parts of the signal in order to help prevent clipping and distortion that can occur when multiple sounds are played and multiplexed together at once. GainNode The GainNode interface represents a change in volume. It is an AudioNode audio-processing module that causes a given gain to be applied to the input data before its propagation to the output. WaveShaperNode The WaveShaperNode interface represents a non-linear distorter. It is an AudioNode that use a curve to apply a waveshaping distortion to the signal. Beside obvious distortion effects, it is often used to add a warm feeling to the signal. PeriodicWave Describes a periodic waveform that can be used to shape the output of an OscillatorNode. IIRFilterNode Implements a general infinite impulse response (IIR) filter; this type of filter can be used to implement tone control devices and graphic equalizers as well. Defining audio destinations Once you are done processing your audio, these interfaces define where to output it. AudioDestinationNode The AudioDestinationNode interface represents the end destination of an audio source in a given context --- usually the speakers of your device. MediaStreamAudioDestinationNode The MediaStreamAudioDestinationNode interface represents an audio destination consisting of a WebRTC MediaStream with a single AudioMediaStreamTrack, which can be used in a similar way to a MediaStream obtained from getUserMedia(). It is an AudioNode that acts as an audio destination. Data analysis and visualization If you want to extract time, frequency, and other data from your audio, the AnalyserNode is what you need. AnalyserNode The AnalyserNode interface represents a node able to provide real-time frequency and time-domain analysis information, for the purposes of data analysis and visualization. Splitting and merging audio channels To split and merge audio channels, you'll use these interfaces. ChannelSplitterNode The ChannelSplitterNode interface separates the different channels of an audio source out into a set of mono outputs. ChannelMergerNode The ChannelMergerNode interface reunites different mono inputs into a single output. Each input will be used to fill a channel of the output. Audio spatialization These interfaces allow you to add audio spatialization panning effects to your audio sources. AudioListener The AudioListener interface represents the position and orientation of the unique person listening to the audio scene used in audio spatialization. PannerNode The PannerNode interface represents the position and behavior of an audio source signal in 3D space, allowing you to create complex panning effects. StereoPannerNode The StereoPannerNode interface represents a simple stereo panner node that can be used to pan an audio stream left or right. Audio processing in JavaScript Using audio worklets, you can define custom audio nodes written in JavaScript or WebAssembly. Audio worklets implement the Worklet interface, a lightweight version of the Worker interface. AudioWorklet The AudioWorklet interface is available through the AudioContext object's audioWorklet, and lets you add modules to the audio worklet to be executed off the main thread. AudioWorkletNode The AudioWorkletNode interface represents an AudioNode that is embedded into an audio graph and can pass messages to the corresponding AudioWorkletProcessor. AudioWorkletProcessor The AudioWorkletProcessor interface represents audio processing code running in a AudioWorkletGlobalScope that generates, processes, or analyses audio directly, and can pass messages to the corresponding AudioWorkletNode. AudioWorkletGlobalScope The AudioWorkletGlobalScope interface is a WorkletGlobalScope-derived object representing a worker context in which an audio processing script is run; it is designed to enable the generation, processing, and analysis of audio data directly using JavaScript in a worklet thread rather than on the main thread. Obsolete: script processor nodes Before audio worklets were defined, the Web Audio API used the ScriptProcessorNode for JavaScript-based audio processing. Because the code runs in the main thread, they have bad performance. The ScriptProcessorNode is kept for historic reasons but is marked as deprecated. ScriptProcessorNode The ScriptProcessorNode interface allows the generation, processing, or analyzing of audio using JavaScript. It is an AudioNode audio-processing module that is linked to two buffers, one containing the current input, one containing the output. An event, implementing the AudioProcessingEvent interface, is sent to the object each time the input buffer contains new data, and the event handler terminates when it has filled the output buffer with data.[audioprocess](https://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode/audioprocess_event "/en-US/docs/Web/Events/audioprocess") (event) The audioprocess event is fired when an input buffer of a Web Audio API ScriptProcessorNode is ready to be processed. AudioProcessingEvent The AudioProcessingEvent represents events that occur when a ScriptProcessorNode input buffer is ready to be processed. Offline/background audio processing It is possible to process/render an audio graph very quickly in the background --- rendering it to an AudioBuffer rather than to the device's speakers --- with the following. OfflineAudioContext The OfflineAudioContext interface is an AudioContext interface representing an audio-processing graph built from linked together AudioNode s. In contrast with a standard AudioContext, an OfflineAudioContext doesn't really render the audio but rather generates it, as fast as it can, in a buffer.[complete](https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext/complete_event "/en-US/docs/Web/Events/complete") (event) The complete event is fired when the rendering of an OfflineAudioContext is terminated. OfflineAudioCompletionEvent The OfflineAudioCompletionEvent represents events that occur when the processing of an OfflineAudioContext is terminated. The [complete](https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext/complete_event "/en-US/docs/Web/Events/complete") event uses this interface. Guides and tutorials Advanced techniques: Creating and sequencing audio In this tutorial, we're going to cover sound creation and modification, as well as timing and scheduling. We're going to introduce sample loading, envelopes, filters, wavetables, and frequency modulation. If you're familiar with these terms and you're looking for an introduction to their application within with the Web Audio API, you've come to the right place. Background audio processing using AudioWorklet This article explains how to create an audio worklet processor and use it in a Web Audio application. Basic concepts behind Web Audio API This article explains some of the audio theory behind how the features of the Web Audio API work, to help you make informed decisions while designing how audio is routed through your app. Controlling multiple parameters with ConstantSourceNode This article demonstrates how to use a ConstantSourceNode to link multiple parameters together so they share the same value, which can be changed by setting the value of the ConstantSourceNode.offset parameter. Example and tutorial: Simple synth keyboard This article presents the code and working demo of a video keyboard you can play using the mouse. The keyboard allows you to switch among the standard waveforms as well as one custom waveform, and you can control the main gain using a volume slider beneath the keyboard. This example makes use of the following Web API interfaces: AudioContext, OscillatorNode, PeriodicWave, and GainNode. Migrating from webkitAudioContext In this article, we cover the differences in Web Audio API since it was first implemented in WebKit and how to update your code to use the modern Web Audio API. Tools for analyzing Web Audio usage While working on your Web Audio API code, you may find that you need tools to analyze the graph of nodes you create or to otherwise debug your work. This article discusses tools available to help you do that. Using IIR filters The IIRFilterNode interface of the Web Audio API is an AudioNode processor that implements a general infinite impulse response (IIR) filter; this type of filter can be used to implement tone control devices and graphic equalizers, and the filter response parameters can be specified, so that it can be tuned as needed. This article looks at how to implement one, and use it in a simple example. Using the Web Audio API Let's take a look at getting started with the Web Audio API. We'll briefly look at some concepts, then study a simple boombox example that allows us to load an audio track, play and pause it, and change its volume and stereo panning. Visualizations with Web Audio API One of the most interesting features of the Web Audio API is the ability to extract frequency, waveform, and other data from your audio source, which can then be used to create visualizations. This article explains how, and provides a couple of basic use cases. Web Audio API best practices There's no strict right or wrong way when writing creative code. As long as you consider security, performance, and accessibility, you can adapt to your own style. In this article, we'll share a number of best practices --- guidelines, tips, and tricks for working with the Web Audio API. Web audio spatialization basics As if its extensive variety of sound processing (and other) options wasn't enough, the Web Audio API also includes facilities to allow you to emulate the difference in sound as a listener moves around a sound source, for example panning as you move around a sound source inside a 3D game. The official term for this is spatialization, and this article will cover the basics of how to implement such a system.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    dynamic-time-warping Dynamic Time Warping Triggered Guitar Effects Project: DTW Algorithm: This is an embedded Microsoft Office presentation, powered by Office. Project: This is an embedded Microsoft Office presentation, powered by Office.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Dynamic Time Warping Algorithm Explained (Python) Dynamic Time Warping Algorithm Explained (Python) In this world which is getting dominated by Internet of Things (IoT), there is an increasing need to understand signals from devices installed in households, shopping malls, factories and offices. For example, any voice assistant detects, authenticates and interprets commands from humans even if it is slow or fast. Our voice tone tends to be different during different times of the day. In the early morning after we get up from bed, we interact with a slower, heavier and lazier tone compared to other times of the day. These devices treat the signals as time series and compare the peaks, troughs and slopes by taking into account the varying lags and phases in the signals to come up with a similarity score. One of the most common algorithms used to accomplish this is Dynamic Time Warping (DTW). It is a very robust technique to compare two or more Time Series by ignoring any shifts and speed. As part of Walmart Real Estate team, I am working on understanding the energy consumption pattern of different assets like refrigeration units, dehumidifiers, lighting, etc. installed in the retail stores.This will help in improving quality of data collected from IoT sensors, detect and prevent faults in the systems and improve energy consumption forecasting and planning. This analysis involves time series of energy consumption during different times of a day i.e. different days of a week, weeks of a month and months of a year. Time series forecasting often gives bad predictions when there is sudden shift in phase of the energy consumption due to unknown factors. For example if the defrost schedule, items refresh routine for a refrigeration unit, or weather changes suddenly and are not captured to explain the phase shifts of energy consumption, it is important to detect these change points. In the example below, the items refresh routine of a store has shifted by 2 hours on Tuesday leading the shift in peak energy consumption of refrigeration units and this information was not available to us for many such stores. The peak at 2 am got shifted to 4 am. DTW when run recursively for consecutive days can identify the cases for which phase shift occurred without much change in shape of signals. The training data can be restricted to Tuesday onwards to improve the prediction of energy consumption in future in this case as phase shift was detected on Tuesday. The setup improved the predictions substantially ( > 50%) for the stores for which the reason of shift was not known. This was not possible by traditional ways of one to one comparison of signals. In this blog, I will explain how DTW algorithm works and throw some light on the calculation of the similarity score between two time series and its implementation in python. Most of the contents in this blog have been sourced from this paper, also mentioned in the references section below. 2. Why do we need DTW ? Any two time series can be compared using euclidean distance or other similar distances on a one to one basis on time axis. The amplitude of first time series at time T will be compared with amplitude of second time series at time T. This will result into a very poor comparison and similarity score even if the two time series are very similar in shape but out of phase in time. DTW compares amplitude of first signal at time T with amplitude of second signal at time T+1 and T-1 or T+2 and T-2. This makes sure it does not give low similarity score for signals with similar shape and different phase. How it works? Let us take two time series signals P and Q Series 1 (P) : 1,4,5,10,9,3,2,6,8,4 Series 2 (Q): 1,7,3,4,1,10,5,4,7,4 Step 1 : Empty Cost Matrix Creation Create an empty cost matrix M with x and y labels as amplitudes of the two series to be compared. Step 2: Cost Calculation Fill the cost matrix using the formula mentioned below starting from left and bottom corner. M(i, j) = |P(i) --- Q(j)| + min ( M(i-1,j-1), M(i, j-1), M(i-1,j) ) where M is the matrix i is the iterator for series P j is the iterator for series Q Let us take few examples (11,3 and 8 ) to illustrate the calculation as highlighted in the below table. for 11,|10 --4| + min( 5, 12, 5 )= 6 + 5= 11 Similarly for 3,|4 --1| + min( 0 )= 3+ 0= 3 and for 8,|1 --3| + min( 6)= 2 + 6= 8 The full table will look like this: Step 3: Warping Path Identification Identify the warping path starting from top right corner of the matrix and traversing to bottom left. The traversal path is identified based on the neighbour with minimum value. In our example it starts with 15 and looks for minimum value i.e. 15 among its neighbours 18, 15 and 18. The next number in the warping traversal path is 14. This process continues till we reach the bottom or the left axis of the table. The final path will look like this: Let this warping path series be called as d. d = [15,15,14,13,11,9,8,8,4,4,3,0] Step 4: Final Distance Calculation Time normalised distance , D where k is the length of the series d. k = 12 in our case. D = ( 15 + 15 + 14 + 13 + 11 + 9 + 8 + 8 + 4 + 4 + 3 + 0 ) /12= 104/12= 8.63 Let us take another example with two very similar time series with unit time shift difference. Cost matrix and warping path will look like this. DTW distance ,D =( 0 + 0 + 0 + 0 + 0 +0 +0 +0 +0 +0 +0 ) /11= 0 Zero DTW distance implies that the time series are very similar and that is indeed the case as observed in the plot. Resummation (Spaced Repitition) Dynamic Time Warping (DTW) is a way to compare two -usually temporal- sequences that do not sync up perfectly. It is a method to calculate the optimal matching between two sequences. DTW is useful in many domains such as speech recognition, data mining, financial markets, etc. It's commonly used in data mining to measure the distance between two time-series. In this post, we will go over the mathematics behind DTW. Then, two illustrative examples are provided to better understand the concept. If you are not interested in the math behind it, please jump to examples. Formulation Let's assume we have two sequences like the following:𝑋=𝑥[1], 𝑥[2], ..., x[i], ..., x[n] Y=y[1], y[2], ..., y[j], ..., y[m] The sequences 𝑋 and 𝑌 can be arranged to form an 𝑛-by-𝑚 grid, where each point (𝑖, j) is the alignment between 𝑥[𝑖] and 𝑦[𝑗]. A warping path 𝑊 maps the elements of 𝑋 and 𝑌 to minimize the distance between them. 𝑊 is a sequence of grid points (𝑖, 𝑗). We will see an example of the warping path later. Warping Path and DTW distance The Optimal path to (𝑖𝑘, 𝑗𝑘) can be computed by: where 𝑑 is the Euclidean distance. Then, the overall path cost can be calculated as Restrictions on the Warping function The warping path is found using a dynamic programming approach to align two sequences. Going through all possible paths is "combinatorically explosive" [1]. Therefore, for efficiency purposes, it's important to limit the number of possible warping paths, and hence the following constraints are outlined: Boundary Condition: This constraint ensures that the warping path begins with the start points of both signals and terminates with their endpoints. Monotonicity condition: This constraint preserves the time-order of points (not going back in time). Continuity (step size) condition: This constraint limits the path transitions to adjacent points in time (not jumping in time). In addition to the above three constraints, there are other less frequent conditions for an allowable warping path: Warping window condition: Allowable points can be restricted to fall within a given warping window of width 𝜔 (a positive integer). Slope condition: The warping path can be constrained by restricting the slope, and consequently avoiding extreme movements in one direction. An acceptable warping path has combinations of chess king moves that are: Horizontal moves: (𝑖, 𝑗) → (𝑖, 𝑗+1) Vertical moves: (𝑖, 𝑗) → (𝑖+1, 𝑗) Diagonal moves: (𝑖, 𝑗) → (𝑖+1, 𝑗+1) Implementation Let's import all python packages we need. import pandas as pd import numpy as np# Plotting Packages import matplotlib.pyplot as plt import seaborn as sbn# Configuring Matplotlib import matplotlib as mpl mpl.rcParams['figure.dpi'] = 300 savefig options = dict(format="png", dpi=300, bbox inches="tight")# Computation packages from scipy.spatial.distance import euclidean from fastdtw import fastdtw Let's define a method to compute the accumulated cost matrix D for the warp path. The cost matrix uses the Euclidean distance to calculate the distance between every two points. The methods to compute the Euclidean distance matrix and accumulated cost matrix are defined below: Example 1 In this example, we have two sequences x and y with different lengths. Create two sequences\ x = [3, 1, 2, 2, 1] y = [2, 0, 0, 3, 3, 1, 0] We cannot calculate the Euclidean distance between x and y since they don't have equal lengths. Example 1: Euclidean distance between x and y (is it possible? 🤔) (Image by Author) Compute DTW distance and warp path Many Python packages calculate the DTW by just providing the sequences and the type of distance (usually Euclidean). Here, we use a popular Python implementation of DTW that is FastDTW which is an approximate DTW algorithm with lower time and memory complexities [2]. dtw distance, warp path = fastdtw(x, y, dist=euclidean) Note that we are using SciPy's distance function Euclidean that we imported earlier. For a better understanding of the warp path, let's first compute the accumulated cost matrix and then visualize the path on a grid. The following code will plot a heatmap of the accumulated cost matrix. cost matrix = compute accumulated cost matrix(x, y) Example 1: Python code to plot (and save) the heatmap of the accumulated cost matrix Example 1: Accumulated cost matrix and warping path (Image by Author) The color bar shows the cost of each point in the grid. As can be seen, the warp path (blue line) is going through the lowest cost on the grid. Let's see the DTW distance and the warping path by printing these two variables. DTW distance: 6.0 Warp path: [(0, 0), (1, 1), (1, 2), (2, 3), (3, 4), (4, 5), (4, 6)] The warping path starts at point (0, 0) and ends at (4, 6) by 6 moves. Let's also calculate the accumulated cost most using the functions we defined earlier and compare the values with the heatmap. cost matrix = compute accumulated cost matrix(x, y) print(np.flipud(cost_matrix)) # Flipping the cost matrix for easier comparison with heatmap values!>>> [[32. 12. 10. 10. 6.] [23. 11. 6. 6. 5.] [19. 11. 5. 5. 9.] [19. 7. 4. 5. 8.] [19. 3. 6. 10. 4.] [10. 2. 6. 6. 3.] [ 1. 2. 2. 2. 3.]] The cost matrix is printed above has similar values to the heatmap. Now let's plot the two sequences and connect the mapping points. The code to plot the DTW distance between x and y is given below. Example 1: Python code to plot (and save) the DTW distance between x and y Example 1: DTW distance between x and y (Image by Author) Example 2 In this example, we will use two sinusoidal signals and see how they will be matched by calculating the DTW distance between them. Example 2: Generate two sinusoidal signals (x1 and x2) with different lengths Just like Example 1, let's calculate the DTW distance and the warp path for *x1 *and *x2 *signals using FastDTW package. distance, warp_path = fastdtw(x1, x2, dist=euclidean) Example 2: Python code to plot (and save) the DTW distance between x1 and x2 Example 2: DTW distance between x1 and x2 (Image by Author) As can be seen in above figure, the DTW distance between the two signals is particularly powerful when the signals have similar patterns. The extrema (maximum and minimum points) between the two signals are correctly mapped. Moreover, unlike Euclidean distance, we may see many-to-one mapping when DTW distance is used, particularly if the two signals have different lengths. You may spot an issue with dynamic time warping from the figure above. Can you guess what it is? The issue is around the head and tail of time-series that do not properly match. This is because the DTW algorithm cannot afford the warping invariance for at the endpoints. In short, the effect of this is that a small difference at the sequence endpoints will tend to contribute disproportionately to the estimated similarity[3]. Conclusion DTW is an algorithm to find an optimal alignment between two sequences and a useful distance metric to have in our toolbox. This technique is useful when we are working with two non-linear sequences, particularly if one sequence is a non-linear stretched/shrunk version of the other. The warping path is a combination of "chess king" moves that starts from the head of two sequences and ends with their tails. You can find the Jupyter notebook for this blog post here. Thanks for reading! References[1] Donald J. Berndt and James Clifford, Using Dynamic Time Warping to Find Patterns in Time Series, 3rd International Conference on Knowledge Discovery and Data Mining[2] Salvador, S. and P. Chan, FastDTW: Toward accurate dynamic time warping in linear time and space(2007), Intelligent Data Analysis[3] Diego Furtado Silva, et al., On the effect of endpoints on dynamic time warping (2016), SIGKDD Workshop on Mining and Learning from Time Series Useful Links[1] https://nipunbatra.github.io/blog/ml/2014/05/01/dtw.html[2] https://databricks.com/blog/2019/04/30/understanding-dynamic-time-warping.html Sounds like time traveling or some kind of future technic, however, it is not. Dynamic Time Warping is used to compare the similarity or calculate the distance between two arrays or time series with different length. Suppose we want to calculate the distance of two equal-length arrays: a = [1, 2, 3] b = [3, 2, 2] How to do that? One obvious way is to match up a and b in 1-to-1 fashion and sum up the total distance of each component. This sounds easy, but what if a and b have different lengths? a = [1, 2, 3] b = [2, 2, 2, 3, 4] How to match them up? Which should map to which? To solve the problem, there comes dynamic time warping. Just as its name indicates, to warp the series so that they can match up. Use Cases Before digging into the algorithm, you might have the question that is it useful? Do we really need to compare the distance between two unequal-length time series? Yes, in a lot of scenarios DTW is playing a key role. Sound Pattern Recognition One use case is to detect the sound pattern of the same kind. Suppose we want to recognise the voice of a person by analysing his sound track, and we are able to collect his sound track of saying Hello in one scenario. However, people speak in the same word in different ways, what if he speaks hello in a much slower pace like Heeeeeeelloooooo , we will need an algorithm to match up the sound track of different lengths and be able to identify they come from the same person. Stock Market In a stock market, people always hope to be able to predict the future, however using general machine learning algorithms can be exhaustive, as most prediction task requires test and training set to have the same dimension of features. However, if you ever speculate in the stock market, you will know that even the same pattern of a stock can have very different length reflection on klines and indicators. Definition & Idea A concise explanation of DTW from wiki, In time series analysis, dynamic time warping (DTW) is one of the algorithms for measuring similarity between two temporal sequences, which may vary in speed. DTW has been applied to temporal sequences of video, audio, and graphics data --- indeed, any data that can be turned into a linear sequence can be analysed with DTW. The idea to compare arrays with different length is to build one-to-many and many-to-one matches so that the total distance can be minimised between the two. Suppose we have two different arrays red and blue with different length: Clearly these two series follow the same pattern, but the blue curve is longer than the red. If we apply the one-to-one match, shown in the top, the mapping is not perfectly synced up and the tail of the blue curve is being left out. DTW overcomes the issue by developing a one-to-many match so that the troughs and peaks with the same pattern are perfectly matched, and there is no left out for both curves(shown in the bottom top). Rules In general, DTW is a method that calculates an optimal match between two given sequences (e.g. time series) with certain restriction and rules(comes from wiki): Every index from the first sequence must be matched with one or more indices from the other sequence and vice versa The first index from the first sequence must be matched with the first index from the other sequence (but it does not have to be its only match) The last index from the first sequence must be matched with the last index from the other sequence (but it does not have to be its only match) The mapping of the indices from the first sequence to indices from the other sequence must be monotonically increasing, and vice versa, i.e. if j > i are indices from the first sequence, then there must not be two indices l > k in the other sequence, such that index i is matched with index l and index j is matched with index k , and vice versa The optimal match is denoted by the match that satisfies all the restrictions and the rules and that has the minimal cost, where the cost is computed as the sum of absolute differences, for each matched pair of indices, between their values. To summarise is that head and tail must be positionally matched, no cross-match and no left out. Implementation The implementation of the algorithm looks extremely concise: where DTW[i, j] is the distance between s[1:i] and t[1:j] with the best alignment. The key lies in: DTW[i, j] := cost + minimum(DTW[i-1, j ], DTW[i , j-1], DTW[i-1, j-1]) Which is saying that the cost of between two arrays with length i and j equals the distance between the tails + the minimum of cost in arrays with length *` i-1, j _ , _ i, j-1 _ , and _ i-1, j-1*`_ ._ Put it in python would be: Example: The distance between a and b would be the last element of the matrix, which is 2. Add Window Constraint One issue of the above algorithm is that we allow one element in an array to match an unlimited number of elements in the other array(as long as the tail can match in the end), this would cause the mapping to bent over a lot, for example, the following array: a = [1, 2, 3] b = [1, 2, 2, 2, 2, 2, 2, 2, ..., 5] To minimise the distance, the element 2 in array a would match all the 2 in array b , which causes an array b to bent severely. To avoid this, we can add a window constraint to limit the number of elements one can match: The key difference is that now each element is confined to match elements in range i --- w and i + w . The w := max(w, abs(n-m)) guarantees all indices can be matched up. The implementation and example would be: Apply a Package There is also contributed packages available on Pypi to use directly. Here I demonstrate an example using fastdtw: It gives you the distance of two lists and index mapping(the example can extend to a multi-dimension array).
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Fast Fourier Transform Visualizing the Discrete Fourier Transform A couple of years ago I suggested a way of thinking about how the Discrete Fourier Transform works, based on Stuart Riffle's elegant colour-coding of the equation:(Sadly, Stuart's original post describing the equation has been lost to bitrot, and can't even be found in the Wayback Machine.) My contribution was the following analogy: Imagine an enormous speaker, mounted on a pole, playing a repeating sound. The speaker is so large, you can see the cone move back and forth with the sound. Mark a point on the cone, and now rotate the pole. Trace the point from an above-ground view, if the resulting squiggly curve is off-center, then there is frequency corresponding the pole's rotational frequency represented in the sound. Dr Bill Connelly from Australia National University has created an interactive simulation of the analogy. Here, the sound from the speaker is a chord of two tones: just enter their frequency and amplitude, and see how the DFT is calculated from the analysis of the rotation:
    https://bgoonz-blog.netlify.app/images/code.png
  • Fast Fourier Transform
    Discrete Fast Fourier Transform Frequency and the fast Fourier transform If you want to find the secrets of the universe, think in terms of energy, frequency and vibration.— Nikola Tesla This chapter was written in collaboration with SW's father, PW van der Walt. Introducing frequency We'll start by setting up some plotting styles and importing the usual suspects:# Make plots appear inline, set custom plotting style %matplotlib inline import matplotlib.pyplot as plt plt.style.use('style/elegant.mplstyle') import numpy as np The discrete discrete Fourier transform (DFT) is a mathematical technique to convert temporal or spatial data into frequency domain data. Frequency is a familiar concept, due to its colloquial occurrence in the English language: the lowest notes your headphones can rumble out are around 20 Hertz, whereas middle C on a piano lies around 261.6 Hertz. Hertz (Hz), or oscillations per second, in this case literally refers to the number of times per second at which the membrane inside the headphone moves to-and-fro. That, in turn, creates compressed pulses of air which, upon arrival at your eardrum, induces a vibration at the same frequency. So, if you take a simple periodic function, $\sin(10 \times 2 \pi t)$, you can view it as a wave: f = 10 # Frequency, in cycles per second, or Hertz f_s = 100 # Sampling rate, or number of measurements per second t = np.linspace(0, 2, 2 * f_s, endpoint=False) x = np.sin(f * 2 * np.pi * t) fig, ax = plt.subplots() ax.plot(t, x) ax.set_xlabel('Time [s]') ax.set_ylabel('Signal amplitude'); Or you can equivalently think of it as a repeating signal of frequency 10 Hertz (it repeats once every $1/10$ seconds—a length of time we call its period). Although we naturally associate frequency with time, it can equally well be applied to space. E.g., a photo of a textile patterns exhibits high spatial frequency, whereas the sky or other smooth objects have low spatial frequency. Let us now examine our sinusoid through application of the discrete Fourier transform: from scipy import fftpack X = fftpack.fft(x) freqs = fftpack.fftfreq(len(x)) * f_s fig, ax = plt.subplots() ax.stem(freqs, np.abs(X)) ax.set_xlabel('Frequency in Hertz [Hz]') ax.set_ylabel('Frequency Domain (Spectrum) Magnitude') ax.set_xlim(-f_s / 2, f_s / 2) ax.set_ylim(-5, 110) We see that the output of the FFT is a one-dimensional array of the same shape as the input, containing complex values. All values are zero, except for two entries. Traditionally, we visualize the magnitude of the result as a stem plot, in which the height of each stem corresponds to the underlying value.(We explain why you see positive and negative frequencies later on in the sidebox titled "Discrete Fourier transforms". You may also refer to that section for a more in-depth overview of the underlying mathematics.) The Fourier transform takes us from the time to the frequency domain, and this turns out to have a massive number of applications. The fast Fourier transform is an algorithm for computing the discrete Fourier transform; it achieves its high speed by storing and re-using results of computations as it progresses. In this chapter, we examine a few applications of the discrete Fourier transform to demonstrate that the FFT can be applied to multidimensional data (not just 1D measurements) to achieve a variety of goals. Illustration: a birdsong spectrogram Let's start with one of the most common applications, converting a sound signal (consisting of variations of air pressure over time) to a spectrogram. You might have seen spectrograms on your music player's equalizer view, or even on an old-school stereo. Listen to the following snippet of nightingale birdsong (released under CC BY 4.0 at http://www.orangefreesounds.com/nightingale-sound/): from IPython.display import Audio Audio('data/nightingale.wav') If you are reading the paper version of this book, you'll have to use your imagination! It goes something like this: chee-chee-woorrrr-hee-hee cheet-wheet-hoorrr-chi rrr-whi-wheo-wheo-wheo-wheo-wheo-wheo. Since we realise that not everyone is fluent in bird-speak, perhaps it's best if we visualize the measurements—better known as "the signal"—instead. We load the audio file, which gives us the sampling rate (number of measurements per second) as well as audio data as an (N, 2) array—two columns because this is a stereo recording. from scipy.io import wavfile rate, audio = wavfile.read('data/nightingale.wav') We convert to mono by averaging the left and right channels. audio = np.mean(audio, axis=1) Then, calculate the length of the snippet and plot the audio. N = audio.shape[0] L = N / rate print(f'Audio length: {L:.2f} seconds') f, ax = plt.subplots() ax.plot(np.arange(N) / rate, audio) ax.set_xlabel('Time [s]') ax.set_ylabel('Amplitude [unknown]'); Well, that's not very satisfying, is it? If I sent this voltage to a speaker, I might hear a bird chirping, but I can't very well imagine how it would sound like in my head. Is there a better way of seeing what is going on? There is, and it is called the discrete Fourier transform, where discrete refers to the recording consisting of time-spaced sound measurements, in contrast to a continual recording as, e.g., on magnetic tape (remember casettes?). The discrete Fourier transform is often computed using the fast Fourier transform (FFT) algorithm, a name informally used to refer to the DFT itself. The DFT tells us which frequencies or "notes" to expect in our signal. Of course, a bird sings many notes throughout the song, so we'd also like to know when each note occurs. The Fourier transform takes a signal in the time domain (i.e., a set of measurements over time) and turns it into a spectrum—a set of frequencies with corresponding (complex complex) values. The spectrum does not contain any information about time! time So, to find both the frequencies and the time at which they were sung, we'll need to be somewhat clever. Our strategy is as follows: take the audio signal, split it into small, overlapping slices, and apply the Fourier transform to each (a technique known as the Short Time Fourier Transform). We'll split the signal into slices of 1024 samples—that's about 0.02 seconds of audio. Why we choose 1024 and not 1000 we'll explain in a second when we examine performance. The slices will overlap by 100 samples as shown here: Start by chopping up the signal into slices of 1024 samples, each slice overlapping the previous by 100 samples. The resulting slices object contains one slice per row. from skimage import util M = 1024 slices = util.view_as_windows(audio, window_shape=(M,), step=100) print(f'Audio shape: {audio.shape}, Sliced audio shape: {slices.shape}') Generate a windowing function (see the section on windowing for a discussion of the underlying assumptions and interpretations of each) and multiply it with the signal: win = np.hanning(M + 1)[:-1] slices = slices * win It's more convenient to have one slice per column, so we take the transpose: slices = slices.T print('Shape of `slices`:', slices.shape) For each slice, calculate the discrete Fourier transform. The DFT returns both positive and negative frequencies (more on that in "Frequencies and their ordering"), so we slice out the positive M / 2 frequencies for now. spectrum = np.fft.fft(slices, axis=0)[:M // 2 + 1:-1] spectrum = np.abs(spectrum) (As a quick aside, you'll note that we use scipy.fftpack.fft and np.fft interchangeably. NumPy provides basic FFT functionality, which SciPy extends further, but both include an fft function, based on the Fortran FFTPACK.) The spectrum can contain both very large and very small values. Taking the log compresses the range significantly. Here we do a log plot of the ratio of the signal divided by the maximum signal. The specific unit used for the ratio is the decibel, $20 log_{10}\left(\mathrm{amplitude ratio}\right)$. f, ax = plt.subplots(figsize=(4.8, 2.4)) S = np.abs(spectrum) S = 20 * np.log10(S / np.max(S)) ax.imshow(S, origin='lower', cmap='viridis', extent=(0, L, 0, rate / 2 / 1000)) ax.axis('tight') ax.set_ylabel('Frequency [kHz]') ax.set_xlabel('Time [s]'); Much better! We can now see the frequencies vary over time, and it corresponds to the way the audio sounds. See if you can match my earlier description: chee-chee-woorrrr-hee-hee cheet-wheet-hoorrr-chi rrr-whi-wheo-wheo-wheo-wheo-wheo-wheo (I didn't transcribe the section from 3 to 5 seconds—that's another bird). SciPy already includes an implementation of this procedure as scipy.signal.spectrogram, which can be invoked as follows: from scipy import signal freqs, times, Sx = signal.spectrogram(audio, fs=rate, window='hanning', nperseg=1024, noverlap=M - 100, detrend=False, scaling='spectrum') f, ax = plt.subplots(figsize=(4.8, 2.4)) ax.pcolormesh(times, freqs / 1000, 10 * np.log10(Sx), cmap='viridis') ax.set_ylabel('Frequency [kHz]') ax.set_xlabel('Time [s]'); The only differences are that SciPy returns the spectrum magnitude squared (which turns measured voltage into measured energy), and multiplies it by some normalization factors scaling. History Tracing the exact origins of the Fourier transform is tricky. Some related procedures go as far back as Babylonian times, but it was the hot topics of calculating asteroid orbits and solving the heat (flow) equation that led to several breakthroughs in the early 1800s. Whom exactly among Clairaut, Lagrange, Euler, Gauss and D'Alembert we should thank is not exactly clear, but Gauss was the first to describe the fast Fourier transform (an algorithm for computing the discrete Fourier transform, popularized by Cooley and Tukey in 1965). Joseph Fourier, after whom the transform is named, first claimed that arbitrary periodic periodic functions can be expressed as a sum of trigonometric functions. Implementation The discrete Fourier transform functionality in SciPy lives in the `scipy.fftpack module. Among other things, it provides the following DFT-related functionality: fft, fft2, fftn: Compute the discrete Fourier transform using the Fast Fourier Transform algorithm in 1, 2, or n dimensions. ifft, ifft2, ifftn: Compute the inverse of the DFT dct, idct, dst, idst: Compute the cosine and sine transforms, and their inverses. fftshift, ifftshift: Shift the zero-frequency component to the center of the spectrum and back, respectively (more about that soon). fftfreq: Return the discrete Fourier transform sample frequencies. rfft: Compute the DFT of a real sequence, exploiting the symmetry of the resulting spectrum for increased performance. Also used by fft internally when applicable. This is complemented by the following functions in NumPy: np.hanning, np.hamming, np.bartlett, np.blackman, np.kaiser: Tapered windowing functions. It is also used to perform fast convolutions of large inputs by scipy.signal.fftconvolve. SciPy wraps the Fortran FFTPACK library—it is not the fastest out there, but unlike packages such as FFTW, it has a permissive free software license. Choosing the length of the discrete Fourier transform (DFT) A naive calculation of the DFT takes $\mathcal{O}\left(N^2\right)$ operations big_o. How come? Well, you have $N$ (complex) sinusoids of different frequencies ($2 \pi f \times 0, 2 \pi f \times 1, 2 \pi f \times 3, ..., 2 \pi f \times (N - 1)$), and you want to see how strongly your signal corresponds to each. Starting with the first, you take the dot product with the signal (which, in itself, entails $N$ multiplication operations). Repeating this operation $N$ times, once for each sinusoid, then gives $N^2$ operations. Now, contrast that with the fast Fourier transform, which is $\mathcal{O}\left(N \log N\right)$ in the ideal case due to the clever re-use of calculations—a great improvement! However, the classical Cooley-Tukey algorithm implemented in FFTPACK (and used by SciPy) recursively breaks up the transform into smaller (prime-sized) pieces and only shows this improvement for "smooth" input lengths (an input length is considered smooth when its largest prime factor is small). For large prime-sized pieces, the Bluestein or Rader algorithms can be used in conjunction with the Cooley-Tukey algorithm, but this optimization is not implemented in FFTPACK. fast Let us illustrate: import time from scipy import fftpack from sympy import factorint K = 1000 lengths = range(250, 260) # Calculate the smoothness for all input lengths smoothness = [max(factorint(i).keys()) for i in lengths] exec_times = [] for i in lengths: z = np.random.random(i) # For each input length i, execute the FFT K times # and store the execution time times = [] for k in range(K): tic = time.monotonic() fftpack.fft(z) toc = time.monotonic() times.append(toc - tic) # For each input length, remember the *minimum* execution time exec_times.append(min(times)) f, (ax0, ax1) = plt.subplots(2, 1, sharex=True) ax0.stem(lengths, np.array(exec_times) * 10**6) ax0.set_ylabel('Execution time (µs)') ax1.stem(lengths, smoothness) ax1.set_ylabel('Smoothness of input length\n(lower is better)') ax1.set_xlabel('Length of input'); The intuition is that, for smooth input lengths, the FFT can be broken up into many small pieces. After performing the FFT on the first piece, those results can be reused in subsequent computations. This explains why we chose a length of 1024 for our audio slices earlier—it has a smoothness of only 2, resulting in the optimal "radix-2 Cooley-Tukey" algorithm, which computes the FFT using only $(N/2) \log_2 N = 5120$ complex multiplications, instead of $N^2 = 1048576$. Choosing $N = 2^m$ always ensures a maximally smooth $N$ (and, thus, the fastest FFT). More discrete Fourier transform concepts Next, we present a couple of common concepts worth knowing before operating heavy Fourier transform machinery, whereafter we tackle another real-world problem: analyzing target detection in radar data. Frequencies and their ordering For historical reasons, most implementations return an array where frequencies vary from low-to-high-to-low (see the box "Discrete Fourier transforms" for further explanation of frequencies). E.g., when we do the real Fourier transform of a signal of all ones, an input that has no variation and therefore only has the slowest, constant Fourier component (also known as the "DC" or Direct Current component—just electronics jargon for "mean of the signal"), we see this DC component appearing as the first entry: from scipy import fftpack N = 10 fftpack.fft(np.ones(N)) # The first component is np.mean(x) * N When we try the FFT on a rapidly changing signal, we see a high frequency component appear: z = np.ones(10) z[::2] = -1 print(f'Applying FFT to {z}') fftpack.fft(z) Note that the FFT returns a complex spectrum which, in the case of real inputs, is conjugate symmetrical (i.e., symmetric in the real part, and anti-symmetric in the imaginary part): x = np.array([1, 5, 12, 7, 3, 0, 4, 3, 2, 8]) X = fftpack.fft(x) with np.printoptions(precision=2): print("Real part: ", X.real) print("Imaginary part:", X.imag) (And, again, recall that the first component is np.mean(x) * N.) The fftfreq function tells us which frequencies we are looking at specifically: fftpack.fftfreq(10) The result tells us that our maximum component occured at a frequency of 0.5 cycles per sample. This agrees with the input, where a minus-one-plus-one cycle repeated every second sample. Sometimes, it is convenient to view the spectrum organized slightly differently, from high-negative to low to-high-positive (for now, we won't dive too deeply into the concept of negative frequency, other than saying a real-world sine wave is produced by a combination of positive and negative frequencies). We re-shuffle the spectrum using the fftshift function. Discrete Fourier transforms {.callout} The Discrete Fourier Transform (DFT) converts a sequence of $N$ equally spaced real or complex samples $x{0},x{1},\ldots, x{N-1}$ of a function $x(t)$ of time (or another variable, depending on the application) into a sequence of $N$ complex numbers $X{k}$ by the summation$$ X{k}=\sum{n=0}^{N-1}x_{n}e^{-j2\pi kn/N},;k=0,1,\ldots, N-1. $$ With the numbers $X{k}$ known, the inverse DFT _exactly recovers the sample values $x_{n}$ through the summation$$x{n}=\frac{1}{N}\sum{k=0}^{N-1}X_{k}e^{j2\pi kn/N}.$$ Keeping in mind that $e^{j\theta}=\cos\theta+j\sin\theta,$ the last equation shows that the DFT has decomposed the sequence $x{n}$ into a complex discrete Fourier series with coefficients $X{k}$. Comparing the DFT with a continuous complex Fourier series$$x(t)=\sum{n=-\infty}^{\infty}c{n}e^{jn\omega_{0}t},$$ the DFT is a finite series with $N$ terms defined at the equally spaced discrete instances of the angle $(\omega{0}t{n})=2\pi\frac{k}{N}$ in the interval $[0,2\pi)$, i.e. including $0$ and excluding $2\pi$. This automatically normalizes the DFT so that time does not appear explicitly in the forward or inverse transform. If the original function $x(t)$ is limited in frequency to less than half of the sampling frequency (the so-called Nyquist frequency), interpolation between sample values produced by the inverse DFT will usually give a faithful reconstruction of $x(t)$. If $x(t)$ is not limited as such, the inverse DFT can, in general, not be used to reconstruct $x(t)$ by interpolation. Note that this limit does not imply that there are no methods that can do such a reconstruction—see, e.g., compressed sensing, or finite rate of innovation sampling. The function $e^{j2\pi k/N}=\left(e^{j2\pi/N}\right)^{k}=w^{k}$ takes on discrete values between $0$ and $2\pi\frac{N-1}{N}$ on the unit circle in the complex plane. The function $e^{j2\pi kn/N}=w^{kn}$ encircles the origin $n\frac{N-1}{N}$ times, thus generating harmonics of the fundamental sinusoid for which $n=1$. The way in which we defined the DFT leads to a few subtleties when $n>\frac{N}{2}$, for even $N$ odd_n. The function $e^{j2\pi kn/N}$ is plotted for increasing values of $k$ in the figure below, for the cases $n=1$ to $n=N-1$ for $N=16$. When $k$ increases from $k$ to $k+1$, the angle increases by $\frac{2\pi n}{N}$. When $n=1$, the step is $\frac{2\pi}{N}$. When $n=N-1$, the angle increases by $2\pi\frac{N-1}{N}=2\pi-\frac{2\pi}{N}$. Since $2\pi$ is precisely once around the circle, the step equates to $-\frac{2\pi}{N}$, i.e. in the direction of a negative frequency. The components up to $N/2$ represent positive frequency components, those above $N/2$ up to $N-1$ represent negative frequencies. The angle increment for the component $N/2$ for $N$ even advances precisely halfway around the circle for each increment in $k$ and can therefore be interpreted as either a positive or a negative frequency. This component of the DFT represents the Nyquist Frequency, i.e. half of the sampling frequency, and is useful to orientate oneself when looking at DFT graphics. The FFT in turn is simply a special and highly efficient algorithm for calculating the DFT. Whereas a straightforward calculation of the DFT takes of the order of $N^{2}$ calculations to compute, the FFT algorithm requires of the order $N\log N$ calculations. The FFT was the key to the wide-spread use of the DFT in real-time applications and was included in a list of the top $10$ algorithms of the $20^{th}$ century by the IEEE journal Computing in Science & Engineering in the year $2000$. Let's examine the frequency components in a noisy image. Note that, while a static image has no time-varying component, its values do vary across space. The DFT applies equally to either case. First, load and display the image: from skimage import io image = io.imread('images/moonlanding.png') M, N = image.shape f, ax = plt.subplots(figsize=(4.8, 4.8)) ax.imshow(image) print((M, N), image.dtype) Do not adjust your monitor! The image you are seeing is real, although clearly distorted by either the measurement or transmission equipment. To examine the spectrum of the image, we use fftn (instead of fft) to compute the DFT, since it has more than one dimension. The two-dimensional FFT is equivalent to taking the 1-D FFT across rows and then across columns (or vice versa). F = fftpack.fftn(image) F_magnitude = np.abs(F) F_magnitude = fftpack.fftshift(F_magnitude) Again, we take the log of the spectrum to compress the range of values, before displaying: f, ax = plt.subplots(figsize=(4.8, 4.8)) ax.imshow(np.log(1 + F_magnitude), cmap='viridis', extent=(-N // 2, N // 2, -M // 2, M // 2)) ax.set_title('Spectrum magnitude'); Note the high values around the origin (middle) of the spectrum—these coefficients describe the low frequencies or smooth parts of the image; a vague canvas of the photo. Higher frequency components, spread throughout the spectrum, fill in the edges and detail. Peaks around higher frequencies correspond to the periodic noise. From the photo, we can see that the noise (measurement artifacts) is highly periodic, so we hope to remove it by zeroing out the corresponding parts of the spectrum. The image with those peaks suppressed indeed looks quite different!# Set block around center of spectrum to zero K = 40 F_magnitude[M // 2 - K: M // 2 + K, N // 2 - K: N // 2 + K] = 0 # Find all peaks higher than the 98th percentile peaks = F_magnitude < np.percentile(F_magnitude, 98) # Shift the peaks back to align with the original spectrum peaks = fftpack.ifftshift(peaks) # Make a copy of the original (complex) spectrum F_dim = F.copy() # Set those peak coefficients to zero F_dim = F_dim * peaks.astype(int) # Do the inverse Fourier transform to get back to an image # Since we started with a real image, we only look at the real part of # the output. image_filtered = np.real(fftpack.ifft2(F_dim)) f, (ax0, ax1) = plt.subplots(2, 1, figsize=(4.8, 7)) ax0.imshow(fftpack.fftshift(np.log10(1 + np.abs(F_dim))), cmap='viridis') ax0.set_title('Spectrum after suppression') ax1.imshow(image_filtered) ax1.set_title('Reconstructed image'); Windowing If we examine the Fourier transform of a rectangular pulse, we see significant sidelobes in the spectrum: x = np.zeros(500) x[100:150] = 1 X = fftpack.fft(x) f, (ax0, ax1) = plt.subplots(2, 1, sharex=True) ax0.plot(x) ax0.set_ylim(-0.1, 1.1) ax1.plot(fftpack.fftshift(np.abs(X))) ax1.set_ylim(-5, 55); In theory, you would need a combination of infinitely many sinusoids (frequencies) to represent any abrupt transition; the coefficients would typically have the same sidelobe structure as seen here for the pulse. Importantly, the discrete Fourier transform assumes that the input signal is periodic. If the signal is not, the assumption is simply that, right at the end of the signal, it jumps back to its beginning value. Consider the function, $x(t)$, shown here: We only measure the signal for a short time, labeled $T_{eff}$. The Fourier transform assumes that $x(8) = x(0)$, and that the signal is continued as the dashed, rather than the solid line. This introduces a big jump at the edge, with the expected oscillation in the spectrum: t = np.linspace(0, 1, 500) x = np.sin(49 * np.pi * t) X = fftpack.fft(x) f, (ax0, ax1) = plt.subplots(2, 1) ax0.plot(x) ax0.set_ylim(-1.1, 1.1) ax1.plot(fftpack.fftfreq(len(t)), np.abs(X)) ax1.set_ylim(0, 190); Instead of the expected two lines, the peaks are spread out in the spectrum. We can counter this effect by a process called windowing. The original function is multiplied with a window function such as the Kaiser window $K(N,\beta)$. Here we visualize it for $\beta$ ranging from 0 to 100: f, ax = plt.subplots() N = 10 beta_max = 5 colormap = plt.cm.plasma norm = plt.Normalize(vmin=0, vmax=beta_max) lines = [ ax.plot(np.kaiser(100, beta), color=colormap(norm(beta))) for beta in np.linspace(0, beta_max, N) ] sm = plt.cm.ScalarMappable(cmap=colormap, norm=norm) sm._A = [] plt.colorbar(sm).set_label(r'Kaiser $\beta$'); By changing the parameter $\beta$, the shape of the window can be changed from rectangular ($\beta=0$, no windowing) to a window that produces signals that smoothly increase from zero and decrease to zero at the endpoints of the sampled interval, producing very low side lobes ($\beta$ typically between 5 and 10) choosing_a_window. The effect of windowing our previous example is noticeable: win = np.kaiser(len(t), 5) x_win = x * win X_win = fftpack.fft(x_win) f, (ax0, ax1) = plt.subplots(2, 1) ax0.plot(x_win) ax0.set_ylim(-1.1, 1.1) ax1.plot(fftpack.fftfreq(len(t)), np.abs(X_win)) ax1.set_ylim(0, 190); Real-world Application: Analyzing Radar Data Linearly modulated FMCW (Frequency-Modulated Continuous-Wave) radars make extensive use of the FFT algorithm for signal processing and provide examples of various applications of the FFT. We will use actual data from an FMCW radar to demonstrate one such an application: target detection. Roughly, an FMCW radar works like this (see box "A simple FMCW radar system" for more detail): A signal with changing frequency is generated. This signal is transmitted by an antenna, after which it travels outwards, away from the radar. When it hits an object, part of the signal is reflected back to the radar, where it is received, multiplied by a copy of the transmitted signal, and sampled, turning it into numbers that are packed into an array. Our challenge is to interpret those numbers to form meaningful results. The multiplication step above is important. From school, recall the trigonometric identity:$ \sin(xt) \sin(yt) = \frac{1}{2} \left[ \sin \left( (x - y)t + \frac{\pi}{2} \right) - \sin \left( (x + y)t + \frac{\pi}{2} \right) \right] $ Thus, if we multiply the received signal by the transmitted signal, we expect two frequency components to appear in the spectrum: one that is the difference in frequencies between the received and transmitted signal, and one that is the sum of their frequencies. We are particularly interested in the first, since that gives us some indication of how long it took the signal to reflect back to the radar (in other words, how far away the object is from us!). We discard the other by applying a low-pass filter to the signal (i.e., a filter that discards any high frequencies). A simple FMCW radar system {.callout} A block diagram of a simple FMCW radar that uses separate transmit and receive antennas is shown above. The radar consists of a waveform generator that generates a sinusoidal signal of which the frequency varies linearly around the required transmit frequency. The generated signal is amplified to the required power level by the transmit amplifier and routed to the transmit antenna via a coupler circuit where a copy of the transmit signal is tapped off. The transmit antenna radiates the transmit signal as an electromagnetic wave in a narrow beam towards the target to be detected. When the wave encounters an object that reflects electromagnetic waves, a fraction of of the energy irradiating the target is reflected back to the receiver as a second electromagnetic wave that propagates in the direction of the radar system. When this wave encounters the receive antenna, the antenna collects the energy in the wave energy impinging on it and converts it to a fluctuating voltage that is fed to the mixer. The mixer multiplies the received signal with a replica of the transmit signal and produces a sinusoidal signal with a frequency equal to the difference in frequency between the transmitted and received signals. The low-pass filter ensures that the received signal is band limited (i.e., does not contain frequencies that we don't care about) and the receive amplifier strengthens the signal to a suitable amplitude for the analog to digital converter (ADC) that feeds data to the computer. To summarize, we should note that: The data that reaches the computer consists of $N$ samples sampled (from the multiplied, filtered signal) at a sample frequency of $f_{s}$. The amplitude of the returned signal varies depending on the strength of the reflection (i.e., is a property of the target object and the distance between the target and the radar). The frequency measured is an indication of the distance of the target object from the radar. To start off, we'll generate some synthetic signals, after which we'll turn our focus to the output of an actual radar. Recall that the radar is increasing its frequency as it transmits at a rate of $S$ Hz/s. After a certain amount of time, $t$, has passed, the frequency will now be $t S$ higher. In that same time span, the radar signal has traveled $d = t / v$ meters, where $v$ is the speed of the transmitted wave through air (roughly the same as the speed of light, $3 \times 10^8$ m/s). Combining the above observations, we can calculate the amount of time it would take the signal to travel to, bounce off, and return from a target that is distance $R$ away:$$ t_R = 2R / v $$ Therefore, the change in frequency for a target at range $R$ will be:$$ f_{d}= t_R S = \frac{2RS}{v}$$ pi = np.pi # Radar parameters fs = 78125 # Sampling frequency in Hz, i.e. we sample 78125 # times per second ts = 1 / fs # Sampling time, i.e. one sample is taken each # ts seconds Teff = 2048.0 * ts # Total sampling time for 2048 samples # (AKA effective sweep duration) in seconds. Beff = 100e6 # Range of transmit signal frequency during the time the # radar samples, known as the "effective bandwidth" # (given in Hz) S = Beff / Teff # Frequency sweep rate in Hz/s # Specification of targets. We made these targets up, imagining they # are objects seen by the radar with the specified range and size R = np.array([100, 137, 154, 159, 180]) # Ranges (in meter) M = np.array([0.33, 0.2, 0.9, 0.02, 0.1]) # Target size P = np.array([0, pi / 2, pi / 3, pi / 5, pi / 6]) # Randomly chosen phase offsets t = np.arange(2048) * ts # Sample times fd = 2 * S * R / 3E8 # Frequency differences for these targets # Generate five targets signals = np.cos(2 * pi * fd * t[:, np.newaxis] + P) # Save the signal associated with the first target as an example for # later inspection v_single = signals[:, 0] # Weigh the signals, according to target size, and sum, to generate # the combined signal seen by the radar v_sim = np.sum(M * signals, axis=1) ## The above code is equivalent to: # # v0 = np.cos(2 * pi * fd[0] * t) # v1 = np.cos(2 * pi * fd[1] * t + pi / 2) # v2 = np.cos(2 * pi * fd[2] * t + pi / 3) # v3 = np.cos(2 * pi * fd[3] * t + pi / 5) # v4 = np.cos(2 * pi * fd[4] * t + pi / 6) # ## Blend them together # v_single = v0 # v_sim = (0.33 * v0) + (0.2 * v1) + (0.9 * v2) + (0.02 * v3) + (0.1 * v4) Above, we generate a synthetic signal, $v_\mathrm{single}$, received when looking at a single target (see figure below). By counting the number of cycles seen in a given time period, we can compute the frequency of the signal and thus the distance to the target. A real radar will rarely receive only a single echo, though. The simulated signal $v\mathrm{sim}$ shows what a radar signal will look like with five targets at different ranges (including two close to one another at 154 and 159 meters), and $v\mathrm{actual}(t)$ shows the output signal obtained with an actual radar. When multiple echoes add together, the result makes little intuitive sense; until, that is, we look at it more carefully through the lens of the discrete Fourier transform. The real-world radar data is read from a NumPy-format .npz file (a light-weight, cross-platform and cross-version compatible storage format). These files can be saved with the np.savez or np.savez_compressed functions. Note that SciPy's io submodule can also easily read other formats, such as MATLAB(R) and NetCDF files. data = np.load('data/radar_scan_0.npz') # Load variable 'scan' from 'radar_scan_0.npz' scan = data['scan'] # The dataset contains multiple measurements, each taken with the # radar pointing in a different direction. Here we take one such as # measurement, at a specified azimuth (left-right position) and elevation # (up-down position). The measurement has shape (2048,). v_actual = scan['samples'][5, 14, :] # The signal amplitude ranges from -2.5V to +2.5V. The 14-bit # analogue-to-digital converter in the radar gives out integers # between -8192 to 8192. We convert back to voltage by multiplying by # $(2.5 / 8192)$. v_actual = v_actual * (2.5 / 8192) Since .npz-files can store multiple variables, we have to select the one we want: data['scan']. That returns a structured NumPy array with the following fields: time : unsigned 64-bit (8 byte) integer ( np.uint64) size : unsigned 32-bit (4 byte) integer ( np.uint32) position az : 32-bit float ( np.float32) el : 32-bit float ( np.float32) region_type : unsigned 8-bit (1 byte) integer ( np.uint8) region_ID : unsigned 16-bit (2 byte) integer ( np.uint16) gain : unsigned 8-bit (1 byte) integer ( np.uin8) samples : 2048 unsigned 16-bit (2 byte) integers ( np.uint16) While it is true that NumPy arrays are homogeneous (i.e., all the elements inside are the same), it does not mean that those elements cannot be compound elements, as is the case here. An individual field is accessed using dictionary syntax: azimuths = scan['position']['az'] # Get all azimuth measurements To summarize what we've seen so far: the shown measurements ($v\mathrm{sim}$ and $v\mathrm{actual}$) are the sum of sinusoidal signals reflected by each of several objects. We need to determine each of the constituent components of these composite radar signals. The FFT is the tool that will do this for us. Signal properties in the frequency domain First, we take the FFTs of our three signals (synthetic single target, synthetic multi-target, and real) and then display the positive frequency components (i.e., components $0$ to $N/2$). These are called the range traces in radar terminology. fig, axes = plt.subplots(3, 1, sharex=True, figsize=(4.8, 2.4)) # Take FFTs of our signals. Note the convention to name FFTs with a # capital letter. V_single = np.fft.fft(v_single) V_sim = np.fft.fft(v_sim) V_actual = np.fft.fft(v_actual) N = len(V_single) with plt.style.context('style/thinner.mplstyle'): axes[0].plot(np.abs(V_single[:N // 2])) axes[0].set_ylabel("$|V_\mathrm{single}|$") axes[0].set_xlim(0, N // 2) axes[0].set_ylim(0, 1100) axes[1].plot(np.abs(V_sim[:N // 2])) axes[1].set_ylabel("$|V_\mathrm{sim} |$") axes[1].set_ylim(0, 1000) axes[2].plot(np.abs(V_actual[:N // 2])) axes[2].set_ylim(0, 750) axes[2].set_ylabel("$|V_\mathrm{actual}|$") axes[2].set_xlabel("FFT component $n$") for ax in axes: ax.grid() Suddenly, the information makes sense! The plot for $|V\mathrm{single}|$ clearly shows a target at component 67, and for $|V\mathrm{sim}|$ shows the targets that produced the signal that was uninterpretable in the time domain. The real radar signal, $|V_\mathrm{actual}|$ shows a large number of targets between component 400 and 500 with a large peak in component 443. This happens to be an echo return from a radar illuminating the high wall of an open-cast mine. To get useful information from the plot, we must determine the range! Again, we use the formula:$$R{n}=\frac{nv}{2B{eff}}$$ In radar terminology, each DFT component is known as a range bin. This equation also defines the range resolution of the radar: targets will only be distinguishable if they are separated by more than two range bins, i.e.$$\Delta R>\frac{1}{B_{eff}}.$$ This is a fundamental property of all types of radar. This result is quite satisfying—but the dynamic range is so large that we could very easily miss some peaks. Let's take the $\log$ as before with the spectrogram: c = 3e8 # Approximately the speed of light and of # electromagnetic waves in air fig, (ax0, ax1, ax2) = plt.subplots(3, 1) def dB(y): "Calculate the log ratio of y / max(y) in decibel." y = np.abs(y) y /= y.max() return 20 * np.log10(y) def log_plot_normalized(x, y, ylabel, ax): ax.plot(x, dB(y)) ax.set_ylabel(ylabel) ax.grid() rng = np.arange(N // 2) * c / 2 / Beff with plt.style.context('style/thinner.mplstyle'): log_plot_normalized(rng, V_single[:N // 2], "$|V_0|$ [dB]", ax0) log_plot_normalized(rng, V_sim[:N // 2], "$|V_5|$ [dB]", ax1) log_plot_normalized(rng, V_actual[:N // 2], "$|V_{\mathrm{actual}}|$ [dB]", ax2) ax0.set_xlim(0, 300) # Change x limits for these plots so that ax1.set_xlim(0, 300) # we are better able to see the shape of the peaks. ax2.set_xlim(0, len(V_actual) // 2) ax2.set_xlabel('range') The observable dynamic range is much improved in these plots. For instance, in the real radar signal the noise floor of the radar has become visible (i.e., the level where electronic noise in the system starts to limit the radar's ability to detect a target). Windowing, applied We're getting there, but in the spectrum of the simulated signal, we still cannot distinguish the peaks at 154 and 159 meters. Who knows what we're missing in the real-world signal! To sharpen the peaks, we'll return to our toolbox and make use of windowing. Here are the signals used thus far in this example, windowed with a Kaiser window with $\beta=6.1$: f, axes = plt.subplots(3, 1, sharex=True, figsize=(4.8, 2.8)) t_ms = t * 1000 # Sample times in milli-second w = np.kaiser(N, 6.1) # Kaiser window with beta = 6.1 for n, (signal, label) in enumerate([(v_single, r'$v_0 [V]$'), (v_sim, r'$v_5 [V]$'), (v_actual, r'$v_{\mathrm{actual}} [V]$')]): with plt.style.context('style/thinner.mplstyle'): axes[n].plot(t_ms, w * signal) axes[n].set_ylabel(label) axes[n].grid() axes[2].set_xlim(0, t_ms[-1]) axes[2].set_xlabel('Time [ms]'); And the corresponding FFTs (or "range traces", in radar terms): V_single_win = np.fft.fft(w * v_single) V_sim_win = np.fft.fft(w * v_sim) V_actual_win = np.fft.fft(w * v_actual) fig, (ax0, ax1,ax2) = plt.subplots(3, 1) with plt.style.context('style/thinner.mplstyle'): log_plot_normalized(rng, V_single_win[:N // 2], r"$|V_{0,\mathrm{win}}|$ [dB]", ax0) log_plot_normalized(rng, V_sim_win[:N // 2], r"$|V_{5,\mathrm{win}}|$ [dB]", ax1) log_plot_normalized(rng, V_actual_win[:N // 2], r"$|V_\mathrm{actual,win}|$ [dB]", ax2) ax0.set_xlim(0, 300) # Change x limits for these plots so that ax1.set_xlim(0, 300) # we are better able to see the shape of the peaks. ax1.annotate("New, previously unseen!", (160, -35), xytext=(10, 15), textcoords="offset points", color='red', size='x-small', arrowprops=dict(width=0.5, headwidth=3, headlength=4, fc='k', shrink=0.1)); Compare these with the earlier range traces. There is a dramatic lowering in side lobe level, but at a price: the peaks have changed in shape, widening and becoming less peaky, thus lowering the radar resolution, that is, the ability of the radar to distinguish between two closely space targets. The choice of window is a compromise between side lobe level and resolution. Even so, referring to the trace for $V_\mathrm{sim}$, windowing has dramatically increased our ability to distinguish the small target from its large neighbor. In the real radar data range trace windowing has also reduced the side lobes. This is most visible in the depth of the notch between the two groups of targets. Radar Images Knowing how to analyze a single trace, we can expand to looking at radar images. The data is produced by a radar with a parabolic reflector antenna. It produces a highly directive round pencil beam with a $2^\circ$ spreading angle between half-power points. When directed with normal incidence at a plane, the radar will illuminate a spot of about $2$ meters in diameter at a distance of 60 meters. Outside this spot, the power drops off quite rapidly, but strong echoes from outside the spot will nevertheless still be visible. By varying the pencil beam's azimuth (left-right position) and elevation (up-down position), we can sweep it across the target area of interest. When reflections are picked up, we can calculate the distance to the reflector (the object hit by the radar signal). Together with the current pencil beam azimuth and elevation, this defines the reflector's position in 3D. A rock slope consists of thousands of reflectors. A range bin can be thought of as a large sphere with the radar at its center that intersects the slope along a ragged line. The scatterers on this line will produce reflections in this range bin. The wavelength of the radar (distance the transmitted wave travels in one oscillation second) is about 30 mm. The reflections from scatterers separated by odd multiples of a quarter wavelength in range, about 7.5 mm, will tend to interfere destructively, while those from scatterers separated by multiples of a half wavelength will tend to interfere constructively at the radar. The reflections combine to produce apparent spots of strong reflections. This specific radar moves its antenna in order to scan small regions consisting of $20^\circ$ azimuth and $30^\circ$ elevation bins scanned in steps of $0.5^\circ$. We will now draw some contour plots of the resulting radar data. Please refer to the diagram below to see how the different slices are taken. A first slice at fixed range shows the strength of echoes against elevation and azimuth. Another two slices at fixed elevation and azimuth respectively shows the slope. The stepped construction of the high wall in an opencast mine is visible in the azimuth plane. data = np.load('data/radar_scan_1.npz') scan = data['scan'] # The signal amplitude ranges from -2.5V to +2.5V. The 14-bit # analogue-to-digital converter in the radar gives out integers # between -8192 to 8192. We convert back to voltage by multiplying by # $(2.5 / 8192)$. v = scan['samples'] * 2.5 / 8192 win = np.hanning(N + 1)[:-1] # Take FFT for each measurement V = np.fft.fft(v * win, axis=2)[::-1, :, :N // 2] contours = np.arange(-40, 1, 2) # ignore MPL layout warnings import warnings warnings.filterwarnings('ignore', '.*Axes.*compatible.*tight_layout.*') f, axes = plt.subplots(2, 2, figsize=(4.8, 4.8), tight_layout=True) labels = ('Range', 'Azimuth', 'Elevation') def plot_slice(ax, radar_slice, title, xlabel, ylabel): ax.contourf(dB(radar_slice), contours, cmap='magma_r') ax.set_title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) ax.set_facecolor(plt.cm.magma_r(-40)) with plt.style.context('style/thinner.mplstyle'): plot_slice(axes[0, 0], V[:, :, 250], 'Range=250', 'Azimuth', 'Elevation') plot_slice(axes[0, 1], V[:, 3, :], 'Azimuth=3', 'Range', 'Elevation') plot_slice(axes[1, 0], V[6, :, :].T, 'Elevation=6', 'Azimuth', 'Range') axes[1, 1].axis('off') 3D visualization We can also visualize the volume in three dimensions. We first compute the argmax (the index of the maximum value) in the range direction. This should give an indication of the range at which the radar beam hit the rock slope. Each argmax index is converted to a three-dimensional (elevation-azimuth-range) coordinate: r = np.argmax(V, axis=2) el, az = np.meshgrid(*[np.arange(s) for s in r.shape], indexing='ij') axis_labels = ['Elevation', 'Azimuth', 'Range'] coords = np.column_stack((el.flat, az.flat, r.flat)) Taking these coordinates, we project them onto the plane (by dropping the range coordinate), and perform a Delaunay tesselation. The tesselation returns a set of indices into our coordinates that define triangles (or simplices). While the triangles are strictly speaking defined on the projected coordinates, we use our original coordinates for the reconstruction, thereby adding back the range component: from scipy import spatial d = spatial.Delaunay(coords[:, :2]) simplexes = coords[d.vertices] For display purposes, we swap the range axis to be the first: coords = np.roll(coords, shift=-1, axis=1) axis_labels = np.roll(axis_labels, shift=-1) Now, Matplotlib's trisurf can be used to visualize the result:# This import initializes Matplotlib's 3D machinery from mpl_toolkits.mplot3d import Axes3D # Set up the 3D axis f, ax = plt.subplots(1, 1, figsize=(4.8, 4.8), subplot_kw=dict(projection='3d')) with plt.style.context('style/thinner.mplstyle'): ax.plot_trisurf(*coords.T, triangles=d.vertices, cmap='magma_r') ax.set_xlabel(axis_labels[0]) ax.set_ylabel(axis_labels[1]) ax.set_zlabel(axis_labels[2], labelpad=-3) ax.set_xticks([0, 5, 10, 15]) # Adjust the camera position to match our diagram above ax.view_init(azim=-50); Further applications of the FFT The examples above show just one of the uses of the FFT in radar. There are many others, such as movement (Doppler) measurement and target recognition. The fast Fourier transform is pervasive, and is seen anywhere from Magnetic Resonance Imaging (MRI) to statistics. With the basic techniques that this chapter outlines in hand, you should be well equipped to use it! Further reading On the Fourier transform: A. Papoulis, The Fourier Integral and Its Applications, McGraw-Hill, 1960. Ronald A. Bracewell, The Fourier Transform and Its Applications, McGraw-Hill, 1986. On radar signal processing: Mark A. Richards, Principles of Modern Radar: Basic Principles, SciTech, 2010 Mark A. Richards, Fundamentals of Radar Signal Processing, McGraw-Hill, 2014. Exercise: The FFT is often used to speed up image convolution (convolution is the application of a moving filter mask). Convolve an image with np.ones((5, 5)), using a) numpy's np.convolve and b) np.fft.fft2. Confirm that the results are identical. Hints: The convolution of x and y is equivalent to ifft2(X * Y), where X and Y are the FFTs of x and y respectively. In order to multiply X and Y, they have to be the same size. Use np.pad to extend x and y with zeros (toward the right and bottom) before taking their FFT. You may see some edge effects. These can be removed by increasing the padding size, so that both x and y have dimensions shape(x) + shape(y) - 1. Solution: from scipy import signal x = np.random.random((50, 50)) y = np.ones((5, 5)) L = x.shape[0] + y.shape[0] - 1 Px = L - x.shape[0] Py = L - y.shape[0] xx = np.pad(x, ((0, Px), (0, Px)), mode='constant') yy = np.pad(y, ((0, Py), (0, Py)), mode='constant') zz = np.fft.ifft2(np.fft.fft2(xx) * np.fft.fft2(yy)).real print('Resulting shape:', zz.shape, ' <-- Why?') z = signal.convolve2d(x, y) print('Results are equal?', np.allclose(zz, z)) The discrete Fourier transform operates on sampled data, in contrast to the standard Fourier transform which is defined for continuous functions.↩ The Fourier transform essentially tells us how to combine a set of sinusoids of varying frequency to form the input signal. The spectrum consists of complex numbers—one for each sinusoid. A complex number encodes two things: a magnitude and an angle. The magnitude is the strength of the sinusoid in the signal, and the angle how much it is shifted in time. At this point, we only care about the magnitude, which we calculate using np.abs.↩ For more on techniques for calculating both (approximate) frequencies and time of occurrence, read up on wavelet analysis.↩ SciPy goes to some effort to preserve the energy in the spectrum. Therefore, when taking only half the components (for N even), it multiplies the remaining components, apart from the first and last components, by two (those two components are "shared" by the two halves of the spectrum). It also normalizes the window by dividing it by its sum.↩ The period can, in fact, also be infinite! The general continuous Fourier transform provides for this possibility. Discrete Fourier transforms are generally defined over a finite interval, and this is implicitly the period of the time domain function that is transformed. In other words, if you do the inverse discrete Fourier transform, you always get a periodic signal out.↩ In computer science, the computational cost of an algorithm is often expressed in "Big O" notation. The notation gives us an indication of how an algorithm's execution time scales with an increasing number of elements. If an algorithm is $\mathcal{O}(N)$, it means its execution time increases linearly with the number of input elements (for example, searching for a given value in an unsorted list is $\mathcal{O}\left(N\right)$). Bubble sort is an example of an $O\left(N^2\right)$ algorithm; the exact number of operations performed may, hypothetically, be $N + \frac{1}{2} N^2$, meaning that the computational cost grows quadratically with the number of input elements.↩ While ideally we don't want to reimplement existing algorithms, sometimes it becomes necessary in order to obtain the best execution speeds possible, and tools like Cython—which compiles Python to C—and Numba—which does just-in-time compilation of Python code—make life a lot easier (and faster!). If you are able to use GPL-licenced software, you may consider using PyFFTW for faster FFTs.↩ We leave it as an exercise for the reader to picture the situation for $N$ odd. In this chapter, all examples use even-order DFTs.↩ The classical windowing functions include Hann, Hamming, and Blackman. They differ in their sidelobe levels and in the broadening of the main lobe (in the Fourier domain). A modern and flexible window function that is close to optimal for most applications is the Kaiser window—a good approximation to the optimal prolate spheroid window, which concentrates the most energy into the main lobe. The Kaiser window can be tuned to suit the particular application, as illustrated in the main text, by adjusting the parameter $\beta$.↩
    https://bgoonz-blog.netlify.app/images/fft.jpg
  • Web-Dev-Hub
    Audio Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Audio Feature Extraction Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Writing Files
    Writing Files The easiest way to write to files in Node.js is to use the fs.writeFile() API. Example: const fs = require('fs'); const content = 'Some content!'; fs.writeFile('/Users/joe/test.txt', content, (err) => { if (err) { console.error(err); return; } //file written successfully }); Alternatively, you can use the synchronous version fs.writeFileSync(): const fs = require('fs'); const content = 'Some content!'; try { const data = fs.writeFileSync('/Users/joe/test.txt', content); //file written successfully } catch (err) { console.error(err); } By default, this API will replace the contents of the file if it does already exist. You can modify the default by specifying a flag: fs.writeFile('/Users/joe/test.txt', content, { flag: 'a+' }, (err) => {}); The flags you'll likely use are r+ open the file for reading and writing w+ open the file for reading and writing, positioning the stream at the beginning of the file. The file is created if not existing a open the file for writing, positioning the stream at the end of the file. The file is created if not existing a+ open the file for reading and writing, positioning the stream at the end of the file. The file is created if not existing(you can find more flags at https://nodejs.org/api/fs.html#fs_file_system_flags) Append to a file A handy method to append content to the end of a file is fs.appendFile() (and its fs.appendFileSync() counterpart): const content = 'Some content!'; fs.appendFile('file.log', content, (err) => { if (err) { console.error(err); return; } //done! }); Using streams All those methods write the full content to the file before returning the control back to your program (in the async version, this means executing the callback) In this case, a better option is to write the file content using streams. 72 Here's a sketch. Error handling is left as an exercise for the reader. let fs = require('fs'), path = require('path'); function dirTree(filename) { let stats = fs.lstatSync(filename), info = { path: filename, name: path.basename(filename) }; if (stats.isDirectory()) { info.type = 'folder'; info.children = fs.readdirSync(filename).map(function (child) { return dirTree(filename + '/' + child); }); } else { // Assuming it's a file. In real life it could be a symlink or // something else! info.type = 'file'; } return info; } if (module.parent == undefined) { // node dirTree.js ~/foo/bar let util = require('util'); console.log(util.inspect(dirTree(process.argv[2]), false, null)); }
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Web Developer Tools What Are Web Development Tools? Client-side Otherwise known as front-end web development, this refers to anything a user can see or engage with—an app or website are good examples. This is about providing a top-notch user experience and smooth interface (usually with a combination of HTML, CSS and various JavaScript libraries. Server-side Otherwise known as back-end web development, this refers to the stuff behind the scenes of apps and websites that users can't see. It's the frameworks, servers and databases that keep things running.Image Source: Paperform When people speak about web development tools (or devtools in the biz), they're usually referring to the apps and software that allows web developers to test and debug the code and interface of a website or web application. Technically, the term doesn't refer to tools that *actually help you build a webpage or app. *But that distinction isn't helpful. Web developers require a range of tools that go beyond debugging and testing—whether it be a remote collaboration tool like Slack, a design tool like Figma, or even just an online forum like StackOverflow. For that reason, we've gone beyond the traditional definition of devtools with the aim of giving a realistic view of the kind of apps and software devs use in their day to day workflows. We think you'll find some familiar favourites, as well as some useful tools to add to your tech stack. What To Consider When Choosing Web Development Tools Whether you're bootstrapping a website from scratch or developing a simple web application, there are few things to keep in mind. Foremost is something that applies to any tool: pick the right option for your specific needs. What works for one project might not work for the next. As a web developer, you constantly need to investigate new tools and ways of doing things. Of course, we all have our favourites, but as a general rule, your tech stack should never be stagnant. There's one other general principle to keep in mind. Tech should simplify your workflow—not complicate it. We know how easy it is to get bogged down in the nerdy details, but when in doubt, ask yourself: does this tool actually make my job easier? Here are a few things to think about beyond these broader considerations: Functionality: Simply, what does each tool help achieve? Does it have a single purpose and can it be replaced by a more feature-rich option? Ease of use: Ensure that the tools that you have control over balance comprehensive features with actually being useable. Scalability: At least some of the tools that you use should be scalable to both small and large projects. Portability: This may not be a gamechanger in the age of remote work, but often web devs travel between clients, the office, home and the local cafe. Customisation: Whether it's a theme on Google Chrome or an add-on for your development environment, we all like to make tools feel unique to us. Security: The security of users, your employer and the sites or apps you are working on always has to be looked after. Cost: If you work for a fancy startup with cash to splash this may not be an issue, but most folks will have to shell out for their own web development tools. Make sure you are getting bang for your buck. A Note On Web Dev Tech Stacks Web development is an all-encompassing term that refers to a bunch of roles. You can split web development into two parts: client-side and server-side. Most of the time, web developers specialise in one of the two. However, there are a few show-offs that can do both—they're referred to as full-stack developers. The term stack is used because the tools that websites and apps use 'stack' on top of each other to build the final product. Check out this example of Paperform's tech stack for example. The 50 Best Web Development Tools In 2021 Alright, as we Antipodeans say, no more beating around the bush. Let's get into the list of the best web development tools we recommend using in 2021.📚 Read our guide on **[ how to get web design clients fast]( https://paperform.co/blog/how-to-get-web-design-clients/).** Code and Text Editors Web developers wouldn't be able to do their jobs fast and efficiently without text editors. A dev's text editor of choice is kind of a holy thing—once devs find a text editor they love, they tend to stick with it for the long haul. Which is why it's such an important decision. It's like a carpenter choosing his hammer, or a Jedi Knight choosing his lightsaber. The good news is you can't go wrong with any listed below: 1. Atom The creators of Atom describe it as a "hackable text editor for the 21st Century". This is in reference to the insane levels of customisation it offers that allow you to make it uniquely yours. Choose from thousands of open-source packages that add new functionality, tweak the look and feel with CSS, or even add your own major features with HTML and JavaScript. Using Atom really is a smooth experience. It works with Mac, Windows or Linux and has all the features you would expect. Plus, there is a nice suite of real-time collaboration tools to help you work with a team. 2. Sublime Text Sublime Text is going to be at the top of any list of the best text editors. It doesn't have all the advanced features other solutions do, but what it lacks in power, it more than makes up for with its beautiful appearance and overall ease of use. With handy keyboard shortcuts, a Command Palette that you won't be able to live without once you use it and a UX to die for, it's an absolute pleasure to use. The context-aware auto-completion feature is particularly useful. It suggests code based on your text, meaning you can cut down on repetitive typing. Add to that an updated Python API, syntax definitions and hyper-fast load times, Sublime Text is hard to go past. 3. Notepad++ Notepad++ is for those of you who don't care about themes and minimalist design and all that fancy stuff. From an aesthetic viewpoint, it's not going to win any awards, but it's still a powerful open-source text editor that has most of your needs covered. Created by a talented software engineer web dev named Don Ho, Notepad++ is a user friendly text editing solution for Windows users. It supports 27 programming languages, synchronised edits and views, and uses Win32 API to produce a tiny program size and faster execution speed.💡Pro Tip: This is also a good option for energy conscious users. By optimising as much as possible, Ho aims to use less CPU power and reduce power consumption, leading to a greener environment. 4. Vim If you're after a highly configurable text editor to build your perfect programming environment, then Vim is the way to go. While it does work out of the box, for the most part, it's a tool that you have to learn to conquer. The cool thing about Vim is that it can be used for any type of text editing—from writing an email to posting blogs in Markup, or of course, editing HTML code. It comes with 200+ syntax files, a comprehensive tag system and integrations with Perl, TCL and Python, and can even act as an OLE automation server in Windows. 5. Visual Code Studio Visual Studio Code (or VS Code) is an open-source code editing program built by Microsoft. It runs everywhere and allows you to do anything from debugging code to inputting Git commands or creating Sass code. There is a bevy of appearance options, including the ability to customise fonts, icons, layout and colour scheme. But the remote development features are what set it apart—you can use a container or a remote machine as a full-featured dev environment. VS Code is the text editor of choice for Dean McPherson, Paperform's co-founder and resident code-geek. He uses the remote plugins for version control and to keep our global dev team working in the same virtual environment. Web Application Frameworks Web application frameworks (or just web frameworks) are software libraries that are designed to help you build web services, resources and APIs. Choosing the right framework for your project is super important. Why? Because it's difficult, time-consuming and expensive to switch to a different solution. It's much easier to stick with one. Below we've curated a list of the best web frameworks in 2021—both front-end and back-end to cover all the bases. This is a big decision and this is only meant as an overview of options, so be sure to do further research before deciding on one. 6. Django Django is a high-level Python framework built by expert developers and used by giant web apps like Reddit, Instagram and Uber. It's secure and scalable, which means it's suitable for a small side hustle or enterprise-scale projects. In a nutshell, Django makes it easier to build great web apps. Fast. The focus here is on enabling devs to create sites and apps with less code (to get nerdy, Django's server-side processing speed is super fast and the file structure is feather-light). Django's goal is to support devs to go from concept to completion as quickly as possible. They achieve this by encouraging clean design and swift development. One of the greatest strengths of Django is its community. They contribute a tonne of useful packages and utilities—a search on PyPI brings up 4,000+ packages free and ready to use. 7. Ruby On Rails Ruby on Rails is a favourite in the dev community. While it requires a certain quality of code, as a general rule it's easy to read, write, monkey patch, test, maintain and deploy, making it any web developer's dream. Rails, as it's called in the biz, is used in a bunch of server-side web apps, including big names like Square, Hulu, Twitch and Shopify. It's a popular framework because straight out of the box you get structures for web services, pages and a database, requiring far less groundwork than other options. So why choose Rails? Well, it's an excellent choice if you're after a robust tool that's simple to use. It has a clean design language, an intuitive workflow, and seamlessly integrates with third-party applications.💡Pro Tip: If you are starting to build your product, Ruby on Rails is an ideal solution to get your MVP up and running. It allows solo web developers to swiftly get projects off the ground and make changes on the fly. 8. Angular Angular (or Angularjs) is a popular Javascript framework created and maintained by Google. It's a cross-platform solution with a cohesive ecosystem of third-party components, meaning you can add a bunch of your own unique functionality improvements. You'll find all the relevant features you'd expect for each stage of the development process, from code generation and splitting to complex animation timelines. The Command-line Interface (CLI) is probably the most notable feature though. it allows you to initialise, develop, scaffold and maintain Angular apps right from the command shell.💡Pro Tip: A JavaScript library is a collection or “library” of prewritten code snippets that can be used to repeat common JavaScript functions. It's also important to note, that which JavaScript framework you use often depends on your client's/business' stack. 9. React React ( React.js) is another great Javascript library built by another ultra-powerful tech company: in this case, Facebook. Made specifically for building user interfaces, it makes it painless to create interactive UIs in a visual way. A component-based system means that individual components manage their own state, and can then be composed to build complex UIs. React can also render on a server using Node, and with React Native you can power mobile apps as well. React is one of the most popular of the many JavaScript frameworks available. Used by WordPress for their backend and Block Editor, it's a platform to consider for any web developer working with user interfaces. 10. Vue Yet another JavaScript library, like React, Vue (or Vue.js) is built for working with user interfaces. Labelling itself as a more “approachable, versatile and performant” alternative, it helps you create a more maintainable and testable codebase. As with other leading frameworks, Vue allows you to take a webpage and split it up into reusable components. Each component then has its own HTML, CSS and JS needed to render that piece of the page—making it faster to make granular changes. Vue offers a more “batteries-included” approach to web application development. It's simple to use and comes with comprehensive documentation and templates to guide you along. 11. Meteor Meteor.js is a free and open-source full-stack isomorphic framework (meaning you can run it both on the client and server side). It might not be as popular as React or Vue, but it's still considered one of the best solutions to enable devs to swiftly build and deploy web, mobile or desktop apps. One of Meteor's biggest selling points is that it seamlessly integrates with the rest of your tech stack—allowing you to focus on building rather than configuring tools to work together. Meteor APM also provides real-time metrics so you can monitor how your app is running. Boasting almost 14,000 packages, over half a million unique installs and used by companies like Ikea, Qualcomm and Honeywell, Meteor is a strong option. 12. ASP.NET Alright, by now this is a familiar story. Prepare for the buzzwords and giant tech companies. ASP.NET is a free, cross-platform framework for building web apps and services developed by Microsoft. What sets it apart from other frameworks is that it uses C# instead of JavaScript. C# supports reference-type (class) and value-type (struct) user-defined types, which can unlock significant performance benefits over JavaScript if you're a more advanced web developer. If you're looking to learn NET then there are plenty of resources. Microsoft has plenty of learning materials and there's an active community on GitHub with over 100,000 people and 3,700 companies contributing. Front-End Frameworks Front-end frameworks (or “CSS frameworks”) are packages containing pre-written, standardised code for easy application. It's kind of like a coding dictionary to help you quickly complete actions without having to come up with code yourself. Keep in mind that there is some crossover with tools we've previously covered. For example, according to the State of JavaScript 2020*, in the US, React, Angular and Vue *are the three most popular front-end frameworks. Here are some other viable options: 13. Bootstrap Bootstrap is a leading open-source CSS framework created by a bunch of the developers behind Twitter (ever heard of it?). Released back in 2011, it's a full-scale tool designed to help you quickly create and customise responsive mobile-first sites. It features Sass variables and mixins (so you can assign variables to a name and refer to it rather than the value itself), extensive prebuilt components and comprehensive JavaScript plugins. In a first for front-end frameworks, it also comes with its own SVG icon library designed to work with your Bootstrap sites. 14. Semantic UI Semantic UI is a component framework for theming websites using what they call “human-friendly HTML” (sorry dogs). What they mean by this is that the tool uses words and classes as exchangeable concepts, giving you the same benefits as BEM without the headache. But the real strength here is the breadth of Semantic UI's components. Whether it's elements, collections, views, modules of behaviours, the whole gamut of interface design is covered. 15. Foundation The folks at Foundation refer to their tool as "the most advanced responsive front-end framework in the world", which is certainly setting the bar high. Though it really is suitable for any device, medium and level of accessibility. Foundation is packed with features to help build content-focused websites, even providing users with HTML, CSS & Javascript templates to speed up the process. You can also use Foundation For Emails to craft HTML emails that look a million bucks on any platform. 16. Materialize Materialize is a modern framework based on Google's Material Design language, combining the classic principles of design with innovation and tech. As a language its goal is to help unify user experience across any platform, which is fitting, as this is a focus at Materialize as well. From the animations to UI elements and everything between, there's a real focus on user experience above all else. That's not to say the technical tools aren't there. They are. It's fast, robust and has a low learning curve. 17. ChromeDevTools Chrome DevTools is the name for the web development tools built into the Google Chrome web browser. No need to download any programs or check if it's got MacOS compatibility—just right click in the browser, choose “Inspect” and get stuck in. It doesn't have as many features as the other options on this list, but it does let you edit pages and diagnose problems with your sites. View and manipulate the DOM, change a page's style sheets (CSS) or use it as a JavaScript debugger. 18. Svelte We love Svelte for two reasons. One, it just sounds awesome and two, it's all about empowering folks to build their projects with *way less code, *which is something we're passionate about here at Paperform. Technically, Svelte isn't a framework or a library. It's a “compiler”, and it's gained quite a reputation in the web dev community for being one of the best frontend frameworks on the market. It's lightweight, SEO-optimised and unlike tools like React or Vue, doesn't require heavy browser processing. Svelte's “killer app” is that is has no virtual Dom. This means there's considerably less re-renders of the UI, leading to a lightning fast experience. Some devs will be put off by this, but it makes it an ideal option for beginners or smaller projects. 19. Ember Ember.js is an open-source JavaScript web framework released back in 2011. Since then it's been adopted by a large chunk of the web dev community and it's easy to see why—using it's simple and, whether you're creating feature-rich apps or client-side websites, the user experience is seamless. Working with Ember is a “batteries included” experience. Out of the box you have all the tools to start building UIs that work on any device. The built-in development environment comes with fast rebuilds, auto-reload and a test runner. Ember Data also lets you set up asynchronous relationships and keep models up to date across your app, which is perfect for remote work. Not sold? Some of the biggest and best development teams in the world use Ember to iterate on their products, including Netflix, Intercom and Apple. Convinced? Package Managers If you've ever installed a bunch of programs on your computer you'll know it's a tedious process. You've got to visit each individual website, download the installer, then set each one up individually. This is fine if all you're doing is downloading Spotify. But back- and front-end developers work with hundreds of programs. Which is why package managers exist. These tools automate the process of installing, upgrading, configuring and removing programs from a computer's operating system. 20. Yarn Yarn is a relatively new package manager built by Facebook. It's known for its speed and stability—about the only two things you need from a package manager. But what sets it apart from similar tools is that it doubles as a project management tool. Installation is a breeze, and if you get stuck, the documentation is comprehensive. The Workspace feature allows you to split your project into sub-components, which is handy for keeping multiple versions of your project live. There is also a (small) plugin library to extend functionality. 21. Node Package Manager (npm) Node Package Manager is a package manager for NodeJS, created in 2009 as an open-source project to give JavaScript devs an easy way to share code modules. The npm Registry consists of more than a million packages—making it the largest software registry in the world. With a quick search you'll find everything from front-end web apps to robots and routers. There is hardly a working web developer out there that wouldn't have used npm at some point. And, now that it's moved to GitHub, npm's already vibrant community is only going to grow. 22. DPKG - Package Manager for Debian Debian is a stable and secure Linux-based operating system extremely popular with web devs. Dpkg is a tool built specifically to manage Debian packages. While dpkg does have a more user-friendly front-end alternative called aptitude, dpkg itself runs entirely via the command line. In terms of functionality, it's definitely a more low-level solution. But if you're trying to handle the installation and removal of Debian software, it's the place to start. For a more advanced tool try Pacman or APT (literally, Advanced Package Tool). Both fetch packages from remote locations and deal with more complex functions. Git Clients In Britain, 'Git' is slang for someone you think is a bit stupid. But in the world of web development, Git is the name for the software used to track changes in file sets. Most of the time it's used to help devs collaborate during software development. A Git *client *is the software you use to work with Git repositories, which can be either remote or locally stored. These allow you to make changes to your Git project (e.g. pushing changes and staging). There are a bunch of different Git clients available across various operating systems.💡Pro Tip: Git is a command line interface and Git clients aren't strictly necessary. It's kind of like using a translator versus learning a language natively. GUIs don't have all the same functionality that a command line client offers, which is why many web devs go that route instead. 23. Github Desktop Built by GitHub, the authority when it comes to all things Git, Github Desktop is a tool that allows you to interact with GitHub from your desktop. It's all about giving you a beautiful interface to cut down on distraction and let you focus on what matters. Whether you're a seasoned veteran or a Git newbie, GitHub Desktop has you covered. Quickly add commits with collaborators, see all open pull requests from your repositories, and easily see before and after shots of your work in progress with expanded image diff support. On top of that there's a heap of automated testing tools to play with. Open-source and available on MacOS and Windows, GitHub is pretty much the default option. 24. GitKraken GitKraken bills itself as the “easiest, safest and most powerful” way to use Git. They understand that Git can be difficult to learn, which is why they offer exhaustive docs, as well as integrations with GitHub, GitLab and Azure DevOps to make adding remotes easy. The UI is equal parts gorgeous and intuitive. One particularly helpful feature is the ability to map complicated commands to a single button or click of the keyboard. If you're working with a team, the visual commit graph also assists you to quickly view who made code changes and when. Other notable features include syntax highlighting, a nifty built-in code editor, interactive rebase and light and dark mode for those late-night coding sessions. 25. SourceTree Sourcetree is a Graphical User Interface (GUI for the cool kids) used to manage Git repository hosts. Built by Atlassian (go Aussies!) it allows you to visualise and manage your repos so you can focus purely on coding. Whether you're just starting out as a web developer or are an old pro, Sourcetree has all the tools you need. Leave the command line behind, or delve deeper to review change-sets, stash or cherry-pick between branches—built-in smart branching keeps development clean and efficient. Sourcetree is available to download for free on both MacOS and Windows. They've got a huge range of tutorials that'll have you up and running in no time. After some initial hiccups, it's now more powerful and reliable than almost any other Git client. API and Testing Cloud Tools Web APIs are a crucial part of web development these days. APIs allow devs to access specific features or data within an application, service or other system. For example, the tech world recently went nuts when Notion announced the beta for their API. By accessing the API devs can now connect other apps with Notion pages and databases.📚 Learn more about **[ Paperform's Notion integration]( https://paperform.co/integrations/notion/).** When testing and building with web APIs it's crucial to have reliable tools. Here are some of the best: 26. Postman Postman is an API platform for building using APIs (duh) with features centred around simplifying the process and streamlining team collaboration. They promise 5x faster development, 4x faster bug fixes and a whopping 10x more effective team collaboration. Do they back it up? The *15 million *developers that use Postman would say so. There are integrated tools for every stage of the API lifecycle, from design, mocking, testing and deploying all the way through to maintenance and deprecation. 27. REST Assured REST Assured is the tool of choice for most web devs working with Java. Made so you don't have to be a HTTP expert to use it, REST Assured enables you to test and validate REST services with the simplicity of more dynamic languages like Ruby. It saves you time and effort through automating part of the boilerplate code required to set up HTTP connections, send and receive requests and parse responses. There are also Given/When/Then test notations to help make tests easily comprehensible. 28. HoppScotch HoppScotch is a lightweight open source API development tool that runs smoothly and looks beautiful. Over the last few months it's gained popularity with the dev community, largely thanks to its balance of advanced functionality and gorgeous design. Whether you need to establish full-duplex communication channels or execute queries with GraphQL, Hoppscotch can handle just about anything you throw at it. You can even add your own translations if English isn't your preferred language. Other features include collections to keep API requests organised, the ability to sync and restore request entries with a click, and real-time connections with WebSocket, MQTT and more. 29. LambdaTest It's crucial that web applications and services work the same way no matter what browser folks use to access them. But you can't check how your HTML, CSS and JavaScript looks on every web browser and operating system on the planet. LambaTest can. This tool performs automated and live interactive testing on 2,000+ real browsers and operating systems to help ensure your web apps look spiffy wherever they appear. It also has the ability to auto-generate full page screenshots across any browser, OS, device or resolution. And with integrated debugging, geolocation testing and seamless collaboration via Asana, Slack and Trello integrations, Lambdatest is a must-have. Web Design and Prototyping Tools It's not enough just to know how to code. Part of being a web designer is understanding what goes into good UI and UX design—from prototyping and wire-framing to creating a visual language for your app. These design tools are vital. 30. Figma Only a few years ago, if you wanted a professional design tool you'd need to spend a whole lot of cash and download complex software. Not anymore. With Figma, you get everything you need to design for the web, completely free and accessible from any browser. From UI, UX and graphic design to wire-framing and diagramming, Figma truly is the all-in-one platform for your design needs. It's like LEGO for web devs. Need to mock up a mobile app? Design an entire UI? Build your client's dream website from scratch? Just use the drag-and-drop editor and away you go. With version history you can even collaborate in real-time and not worry about breaking things. There's a reason the whole internet is raving about it—Figma's a rare tool that you will find yourself actively looking for reasons to use. It's not hyperbole when we say that it's seriously the only design tool you'll need. 31. Adobe XD Adobe XD is just the latest in a long range of excellent design tools from Adobe. With XD you can sketch wireframes and mockups, build interactive prototypes and create high-fidelity designs for any screen, thanks to their vector-based system. Flat images not enough? 3D transform allows you to turn static objects into dynamic, three dimensional designs in a click. Move or rotate objects, add the appearance of depth, or even build unique immersive AR/VR experiences. Above all, Adobe XD succeeds at making your prototypes feel like the real thing—with no coding required. Add user flows, interactions and motion, and save time by using reusable buttons and components. Of course, Adobe XD works seamlessly with the rest of the Adobe suite (editing .PSD files from Photoshop is a particularly handy feature). There are a range of co-editing tools to aid real-time collaboration and 200+ plugins to extend functionality. 32. Sketch Sketch vs Figma is kind of like Apple vs Android: both offer very similar tools, and which one you prefer comes down to preference and your individual workflow. Sketch happens to be the app of choice for companies like Google, Facebook and Xbox. It's easy to use, offers a host of useful keyboard shortcuts, and is lightning fast no matter what you throw at it, from social media designs to working prototypes or fancy new icon sets. Having said that, most web developers agree that Figma's prototyping capabilities are superior to Sketch. They also cite the built-in version history, collaboration features and the way Figma handles colour and text styling. The Auto-Layout is also preferred over Sketch's Smart layout. But. That's not the whole story. Sketch is regarded as being more stable (Figma can be on the buggy side sometimes), having clearer layer organisation, and being faster to load large files. There's also a dark mode, which we all know, is music to any web developer's ear.💡Pro Tip: The Figma vs Sketch battle isn't going to be decided in this blog post. Luckily, Figma is free to use and Sketch has a generous free trial. If you're unsure which is the right choice for you, just try them both. 33. ProtoPie ProtoPie bill themselves as the "easiest way to turn your interaction design ideas into realistic prototypes". It's a no-code creation tool used to create interactive prototypes for mobile, web, desktop or the 'Internet of Things' (IoT). What sets ProtoPie apart is one thing: simplicity. Their goal isn't to be the most complex tool on the market—they want to take the pain out of building workable prototypes, fast. As with any no-code tool, the emphasis is on replacing code with simple buttons and keyboard commands to simplify your workflow. There's a gradual learning curve which makes it great for beginners. Prototypes also interact with each other, meaning you can make interactions across devices. It's not as popular as the big players, but it's certainly a powerful tool. 34. Framer If you're comfortable with code, then Framer is an awesome tool to empower you to create interactive, highly-customisable prototypes. Web devs around the world use it to build apps, websites, design systems and even slick new video game interfaces. What sets it apart from something like Figma? Well, with Framer the idea is that you can work with designs that can *realistically be implemented *with code. It's a bridge for UX designers and developers to collaborate and rapidly experiment in a shared workspace.📚 **Related reading: ** How to stand out as a UX Designer Even if code isn't your thing, Framer is great. The GUI and design elements are on part with Sketch (or at least in the same ballpark) and the built-in prototyping is a breeze to use. There are also plenty of third-party packages to add new elements. 35. Toolset Sick of doing everything with code? Toolset is a WordPress page builder which lets you build custom sites without any code. This is a great option for web developers and designers looking to complete complex projects quickly. Use Toolset to design from within WordPress. Create rich sites that look great on any device and load quickly for the SEO gods. It's got everything you could require to set up custom post types, fields, templates, searches, front-end forms and more. The biggest benefit of Toolset is that it saves you from having to use a bunch of different tools to build WordPress sites—all for a reasonable price of $69. 36. Animator By Haiku Animation is difficult but Animator by Haiku makes it a little bit more palatable. It lets you bring motion design to production, from your initial design tools like Figma to your final codebase. Animator uses an interface called Timeline to choreograph animations in a visual way. You can sequence and animate elements using the built-in curves library, or delve deeper with the custom editor. If you're more comfortable with code, use any code editor of your choice to animate directly from your code. 37. Affinity Designer Adobe Illustrator has long been the industry standard when it comes to creating vector graphics. However, the new kid on the block, Affinity Designer, is certainly giving Adobe a run for its money. You'll find Affinity evangelists all over the net—and for good reason. It offers a silky-smooth experience at a much more affordable price, custom-built with professional illustrators, web designers, game devs and other creatives in mind. Affinity offers many of the same tools as Adobe Illustrator in a beautifully designed (and not bloated) package. Work with vectors and rasters to create concept art, print projects, logos, icons, UIs or just about anything else you can imagine. The biggest drawcard? There's no monthly fee. You can own Affinity Designer for a one-off payment of $84.99 on Windows or Mac or $34.99 on iPad. Collaboration Tools We've covered just about all the technical tools you could possibly need to be a web developer. But whether you're working in-house, at an agency or going it alone as a freelancer, collaboration tools are equally as important as your text editor of choice. Often the success of a project isn't simply down to technical brilliance—it relies on clear and efficient communication. The tools below will help you achieve it. 38. ClickUp Product management tools should do two things: simplify your processes and help you ship products faster. ClickUp does both. With an expansive suite of tools, it is truly “one app to replace them all”, covering tasks, docs, chat, goals and more. Whether you're working solo or in a team, ClickUp lets you map out tasks, better plan your work and see your overall product vision. The major benefit here is the dizzying versatility of the platform. From building mind maps to planning tasks on a Kanban board, you can build out your own custom product management setup. 39. Asana Asana is probably the single most well-known and popular project management and collaboration tool on the market. It's a tool built to stop you shuffling between emails, spreadsheets and other apps to keep organised—from brainstorming to meeting that deadline, you can manage everything with Asana. At Paperform we use Asana to assign tasks to team members, create projects split among our Product, Marketing and Content teams, and monitor deadlines to ensure we're hitting our goals. It's simple and visual, and is particularly excellent for keeping remote teams on the same page. 40. JIRA JIRA is the go-to project management platform for software teams to plan, track and release their products. From creating user stories and planning sprints to the final stages of shipping and data analysis, JIRA is *the *way to take any product to launch and beyond. One big advantage JIRA has over other similar tools is that it's so customisable. It is possible to build the perfect workflow for your specific product or team—this is also a slight drawback, as it results in a slightly steeper learning curve upfront. As you'd expect, it's built with trademark Atlassian polish. And with the Atlassian Marketplace you can connect with over 3,000 first and third-party apps like Slack, Google Drive and GitHub, to extend functionality. 41. Slack If you work online in any capacity and haven't heard of Slack, you must be living under a rock, at the bottom of the ocean, next to a starfish named Patrick. In the last few years, Slack has become synonymous with remote team communication. At its core Slack is a team messaging platform. It cuts down on the need for email by separating conversations into distinct Channels, so you can track topics, ideas and projects without long email threads. This makes it the virtual headquarters for your business. Of course, there's much more to it than simple text chat. Jump on video calls, add integrations with your favourite tools, and even communicate with external clients or folks in other companies Slack isn't just for teams, either. Communities allow you to connect with people in your niche— Java Specialists, Ruby Developers and Python Developers are just a few of the most active. 42. Zoom Occasionally an app or program hits levels of popularity so high that it becomes the noun for what it's used for. This happened to Google long ago (“I'll Google it”) and it happened to video chat tool Zoom in the last year and a half (RIP Skype). This happened for a reason: Zoom is awesome. While nothing replaces the feeling of face-to-face communication, it's the next best thing. Whether you want to chat to your family across the country or liaise with web design clients, it makes video calls ridiculously easy. Zoom is free for 40-minute calls, meaning your meetings come with a convenient end timer. Plus you can record any calls (with your companion's permission), which has become a popular way to record webinars and podcasts.**📚 Related reading: ** How to be a good interviewer Miscellaneous Web Development Tools 43. TypeScript TypeScript is an insanely popular open-source language that builds extra features on top of JavaScript. Essentially, think of regular Java as Clark Kent and TypeScript as Superman—bigger, better, faster and all-round more capable. Devs love Typescript because it makes their job easier. It catches both code and type errors, as well as bugs that can easily be missed. This reduces troubleshooting time, while also saving you the effort of having to track down mistakes manually. The only real downside is that once you try TypeScript you'll find it hard to return to vanilla Java. The good thing is that you don't need to make a binary choice—all valid JavaScript code is also TypeScript code, and TypeScript can be transformed into Java too. If you want clean, simple code with excellent documentation and tools that save you hours of time, TypeScript might be worth a try. Just don't think you can master it in a few minutes, as most devs find there's a steep (albeit worthwhile) learning curve. 44. Sass You might've seen the term Sass mentioned in web dev circles. But what is it? Well, Sass is a CSS preprocessor that extends what you can do with regular CSS, adding special features like variables, nested rules, inheritance (not the monetary type) and mixins. The benefit is that it speeds up your workflow and modularises your code, making edits easier and more efficient to make. It allows you to achieve the same end result as regular CSS, with a fraction of the effort. For example, let's say you're working with a theme colour that you keep having to reuse in your CSS code. Rather than having to retype it every time, you can specify the colour once and save the variable. Then, every time you want to use that colour you just refer to the variable instead of hard-coding it.💡Pro Tip: Sass is compatible with any version of CSS, the only requirement being you need Ruby installed for it to work. Just make sure you don't start using Sass before you have CSS mastered—it's important to get a firm grip of the basics first. 45. Stack Overflow Okay, so this isn't technically a tool. However, it's not hyperbole on the Stack Overflow website when it says, “every developer has a tab open to Stack Overflow”. Ask around—they do. It's the most popular and comprehensive web development community on the internet. Stack Overflow is a public platform that aims to build the single most definitive collection of coding questions and answers. Developers, system admins and data scientists of every shape and size rely on it for accurate information to difficult technical challenges. We're talking the real nitty gritty. If you want to know why InvokeAsync shows an an error in a Blazor component, how to undo the most recent local commits in Git, or why HTML thinks the tag “chucknorris” is a colour, this is the place for you. While it's undoubtedly a gold mine of useful resources, it's important to note that the community can be a bit toxic when it comes to welcoming new web developers. Stack Overflow mods are aware of this (and have added new guidelines in response) but do be wary—and look for existing answers before asking a query of your own.💡Pro Tip: More broadly it would be remiss not to mention your other best friend: Google! Not even the most seasoned web developer knows how to fix everything and you can almost guarantee that you'll find someone out there who's had the same problem as you at some point. 46. Squoosh Image Optimiser Assets. Content. Media. Even the simplest web design project will need basic images and icons. Image optimisation apps allow you to compress image file sizes without affecting quality, which means your sites will stay as fast and responsive as possible. Now, there's no shortage of great image optimisation apps but we love Squoosh. It's a no-frills experience that does exactly what you need it to. Just drag and drop your image into the editor and Squoosh does its thing. You aren't limited to compression either. With the simple interface you can resize, compress or change the image format. The changes are almost instant and the finished product can be downloaded with a click. One drawback is that you can only work with one image at a time. So, if you're working on a large project requiring lots of images, ShortPixel may better suit your needs. 47. ColorPick Eyedropper Chrome Extension Whether you're designing a website, putting together a UI or creating a Canva design, colour is serious business for web developers and designers. Colours are crucial for brand awareness, evoking certain emotions and, most importantly, accessibility. Colour picking tools allow you to identify the Hex codes of elements on the web to gain inspiration or keep designs consistent. There are thousands of tools in this space, but you won't find one easier than ColorPick Eyedropper for Chrome. Just click the extension and hover over any element on *any *webpage. A small box appears with the Hex code and RGB model. These are automatically copied to the clipboard for you to use. If your only experience working with colours was using crayons in kindergarten, Material.io has a great to the Material Design system. 48. Google Lighthouse Technically a part of Chrome Developer Tools, Google Lighthouse deserves its own dedicated entry. It's an open-source, automated tool for improving the quality of web pages. You can run it on any existing web page to audit overall performance, accessibility, best practices and SEO. While you can run it from the command line, or as a Node module, the visual interface within Chrome DevTools is useful for getting actionable insight into what's working (and what is not working) about any given site. There are two new features that extend the functionality somewhat too. Stack Packs allow Lighthouse to detect what platform your site is built on and display more specific guidance based on your unique tools.💡Pro Tip: New Lighthouse plugins also allow you to use the data you've collected to create new audits and reports. Used in tandem with PageSpeed Insights, it's a surefire way to make sure your website is in good shape. 49. A Second Monitor No guide to web development tools would be complete without recommending you treat yourself to a second monitor. The extra screen real estate makes life so much easier and development so much faster. Just think of a world where you can have IDE and terminal open on one screen, and the app that you're debugging on the other. Or Slack on the first, your browser and Stack Overflow on the second, maybe Spotify in the corner for some Lo-Fi beats. With one screen you're constantly cycling through open applications. Half the time you lose a tab, or forget what you're looking for altogether. This takes time, and as we all know, time is money. Treat yourself to a second monitor—it's a whole new world. 50. Paperform For all the advances we've made in the world—sending billionaires to the moon, having the power of a supercomputer in our pockets—it's still weirdly difficult to code beautiful online forms (seriously, PHP is a pain.) That's where Paperform comes in. Paperform empowers you to create beautiful online forms and landing pages without any code. Just use our free-text editor to build anything from basic contact forms to complex eCommerce pages that can be embedded anywhere on the internet. Use our theme tools to get started, then add your own unique tweaks with support for custom HTML and CSS. Developing on WordPress? We've even got a plugin that makes embedding forms on WordPress a breeze—and makes life way easier for you and your clients. But that's not all you can do. Want to collect feedback from satisfied customers? Send a client questionnaire for each new project? Or maybe you want to set up a landing page where you can sell online courses, schedule appointments and grow a mailing list? With Paperform you can do all that and more. And with our 3,000+ Direct and Zapier integrations, connecting with the rest of your tech stack to streamline your web development workflow is so easy your grandma could do it Image Source: Atom Image Source: Sublime Text Image Source: Notepad++ Source: Wikipedia Commons Image Source: Visual Studio Image Source: Django Image Source: Ruby on Rails Image Source: Angular Image Source: React Image Source: Vue Image Source: Meteor Image Source: ASP.NET Image Source: Bootstrap Image Source: Semantic UI Image Source: Foundation Image Source: Materialize Image Source: ChromeDevTools Image Source: Svelte Image Source: Ember Image Source: Yarn Image Source: npm Image Source: DPKG Image Source: Github Desktop Image Source: GitKraken Image Source: Sourcetree Image Source: Postman Image Source: HoppScotch Image Source: LambdaTest Image Source: Figma Image Source: Adobe XD Image Source: Sketch Image Source: ProtoPie Image Source: Framer Image Source: Toolset Image Source: Animator by Haiku Image Source: Affinity Designer Image Source: ClickUp Image Source: Asana Image Source: JIRA Image Source: Slack Image Source: Zoom Image Source: TypeScript Image Source: Sass Image Source: Stack Overflow Image Source: Squoosh Image Source: Paperform Image Source: Google Lighthouse Image Source: Stack Overflow
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Web Standards Checklist Web Standards Checklist The term web standards can mean different things to different people. For some, it is ' table-free sites', for others it is ' using valid code'. However, web standards are much broader than that. A site built to web standards should adhere to standards (HTML, XHTML, XML, CSS, XSLT, DOM, MathML, SVG etc) and pursue best practices (valid code, accessible code, semantically correct code, user-friendly URLs etc). In other words, a site built to web standards should ideally be lean, clean, CSS-based, accessible, usable and search engine friendly. About the checklist This is a guide that can be used: to show the breadth of web standards as a handy tool for developers during the production phase of websites as an aid for developers who are interested in moving towards web standards The checklist Quality of code Does the site use a correct Doctype? Does the site use a Character set? Does the site use Valid (X)HTML? Does the site use Valid CSS? Does the site use any CSS hacks? Does the site use unnecessary classes or ids? Is the code well structured? Does the site have any broken links? How does the site perform in terms of speed/page size? Does the site have JavaScript errors? Degree of separation between content and presentation Does the site use CSS for all presentation aspects (fonts, colour, padding, borders etc)? Are all decorative images in the CSS, or do they appear in the (X)HTML? Accessibility for users Are "alt" attributes used for all descriptive images? Does the site use relative units rather than absolute units for text size? Do any aspects of the layout break if font size is increased? Does the site use visible skip menus? Does the site use accessible forms? Does the site use accessible tables? Is there sufficient colour brightness/contrasts? Is colour alone used for critical information? Is there delayed responsiveness for dropdown menus (for users with reduced motor skills)? Are all links descriptive (for blind users)? Accessibility for devices Does the site work acceptably across modern and older browsers? Is the content accessible with CSS switched off or not supported? Is the content accessible with images switched off or not supported? Does the site work in text browsers such as Lynx? Does the site work well when printed? Does the site work well in Hand Held devices? Does the site include detailed metadata? Does the site work well in a range of browser window sizes? Basic Usability Is there a clear visual hierarchy? Are heading levels easy to distinguish? Is the site's navigation easy to understand? Is the site's navigation consistent? Does the site use consistent and appropriate language? Does the site have a sitemap page and contact page? Are they easy to find? For large sites, is there a search tool? Is there a link to the home page on every page in the site? Are links underlined? Are visited links clearly defined? Site management Does the site have a meaningful and helpful 404 error page that works from any depth in the site? Does the site use friendly URLs? Do your URLs work without "www"? Does the site have a favicon? 1. Quality of code 1.1 Does the site use a correct Doctype? A doctype (short for 'document type declaration') informs the validator which version of (X)HTML you're using, and must appear at the very top of every web page. Doctypes are a key component of compliant web pages: your markup and CSS won't validate without them. Fix your site with the right doctype More: http://www.w3.org/QA/2002/04/valid-dtd-list.html http://css.maxdesign.com.au/listamatic/about-boxmodel.htm http://gutfeldt.ch/matthias/articles/doctypeswitch.html 1.2 Does the site use a Character set? If a user agent (eg. a browser) is unable to detect the character encoding used in a Web document, the user may be presented with unreadable text. This information is particularly important for those maintaining and extending a multilingual site, but declaring the character encoding of the document is important for anyone producing XHTML/HTML or CSS. Tutorial: Character sets & encodings in XHTML, HTML and CSS More: Character encodings 1.3 Does the site use Valid (X)HTML? Valid code will render faster than code with errors. Valid code will render better than invalid code. Browsers are becoming more standards compliant, and it is becoming increasingly necessary to write valid and standards compliant HTML More: W3C Markup Validation Service 1.4 Does the site use Valid CSS? You need to make sure that there aren't any errors in either your HTML or your CSS, since mistakes in either place can result in botched document appearance. Help! My CSS Isn't Working! More: W3C CSS Validation Service 1.5 Does the site use any CSS hacks? Basically, hacks come down to personal choice, the amount of knowledge you have of workarounds, the specific design you are trying to achieve. Standard Hacks? More: CSS Hacks To hack or not to hack CSS filters 1.6 Does the site use unnecessary classes or ids? I've noticed that developers learning new skills often end up with good CSS but poor XHTML. Specifically, the HTML code tends to be full of unnecessary divs and ids. This results in fairly meaningless HTML and bloated style sheets. Markup tactics 1.7 Is the code well structured? Semantically correct markup uses html elements for their given purpose. Well structured HTML has semantic meaning for a wide range of user agents (browsers without style sheets, text browsers, PDAs, search engines etc.) More: Semantic data extractor 1.8 Does the site have any broken links? Broken links can frustrate users and potentially drive customers away. Broken links can also keep search engines from properly indexing your site. More: W3C Link checker 1.9 How does the site perform in terms of speed/page size? Don't make me wait... That's the message users give us in survey after survey. Even broadband users can suffer the slow-loading blues. Speed Up Your Site: Web Site Optimization 1.10 Does the site have JavaScript errors? Internet Explore for Windows allows you to turn on a debugger that will pop up a new window and let you know there are javascript errors on your site. This is available under 'Internet Options' on the Advanced tab. Uncheck 'Disable script debugging'. 2. Degree of separation between content and presentation 2.1 Does the site use CSS for all presentation aspects (fonts, colour, padding, borders etc)? Use style sheets to control layout and presentation Web Content Accessibility Guidelines 1.0 -- checkpoint 3.3 2.2 Are all decorative images in the CSS, or do they appear in the (X)HTML? The aim for web developers is to remove all presentation from the html code, leaving it clean and semantically correct. 3. Accessibility for users 3.1 Are "alt" attributes used for all descriptive images? Provide a text equivalent for every non-text element Web Content Accessibility Guidelines -- checkpoint 1.1 3.2 Does the site use relative units rather than absolute units for text size? Use relative rather than absolute units in markup language attribute values and style sheet property values' Web Content Accessibility Guidelines -- checkpoint 3.4 More: Web Content Accessibility Guidelines -- checkpoint 3.4 How to size text using ems 3.3 Do any aspects of the layout break if font size is increased? Try this simple test. Look at your website in a browser that supports easy incrementation of font size. Now increase your browser's font size. And again. And again... Look at your site. Does the page layout still hold together? It is dangerous for developers to assume that everyone browses using default font sizes. 3.4 Does the site use visible skip menus? A method shall be provided that permits users to skip repetitive navigation links. Section 508 Group related links, identify the group (for user agents), and, until user agents do so, provide a way to bypass the group Web Content Accessibility Guidelines -- checkpoint 13.6...blind visitors are not the only ones inconvenienced by too many links in a navigation area. Recall that a mobility-impaired person with poor adaptive technology might be stuck tabbing through that morass. Keep them visible! 3.5 Does the site use accessible forms? Forms aren't the easiest of things to use for people with disabilities. Navigating around a page with written content is one thing, hopping between form fields and inputting information is another Accessible forms More: Accessible html/xhtml forms Accessible form builder 3.6 Does the site use accessible tables? For data tables, identify row and column headers... For data tables that have two or more logical levels of row or column headers, use markup to associate data cells and header cells. Web Content Accessiblity Guidelines -- checkpoint 5.1 More: How to create accessible tables Accessible table builder Creating accessible tables 3.7 Is there sufficient colour brightness/contrasts? Ensure that foreground and background colour combinations provide sufficient contrast when viewed by someone having colour deficits Web Content Accessibilty Guidelines -- checkpoint 2.2 More: Colour Contrast Analyser 3.8 Is colour alone used for critical information? Ensure that all information conveyed with colour is also available without colour, for example from context or markup Web Content Accessibilty Guidelines -- checkpoint 2.1 There are basically three types of colour deficiency; Deuteranope (a form of red/green colour deficit), Protanope (another form of red/green colour deficit) and Tritanope (a blue/yellow deficit- very rare). More: Colourblind Webpage filter Vischeck 3.9 Is there delayed responsiveness for dropdown menus? Users with reduced motor skills may find dropdown menus hard to use if responsiveness is set too fast. 3.10 Are all links descriptive? Link text should be meaningful enough to make sense when read out of context -- either on its own or as part of a sequence of links. Link text should also be terse. Web Content Accessibility Guidelines 1.0 -- checkpoint 13.1 4. Accessibility for devices 4.1 Does the site work acceptably across modern and older browsers? Before starting to build a CSS-based layout, you should decide which browsers to support and to what level you intend to support them. 4.2 Is the content accessible with CSS switched off or not supported? Some people may visit your site with either a browser that does not support CSS or a browser with CSS switched off. In content is structured well, this will not be an issue. 4.3 Is the content accessible with images switched off or not supported? Some people browse websites with images switched off -- especially people on very slow connections. Content should still be accessible for these people. 4.4 Does the site work in text browsers such as Lynx? This is like a combination of images and CSS switched off. A text-based browser will rely on well structured content to provide meaning. More: Lynx Viewer 4.5 Does the site work well when printed? You can take any (X)HTML document and simply style it for print, without having to touch the markup. Going to print More: Web Design References -- Print 4.6 Does the site work well in Hand Held devices? This is a hard one to deal with until hand held devices consistently support their correct media type. However, some layouts work better in current hand-held devices. The importance of supporting hand held devices will depend on target audiences. 4.7 Does the site include detailed metadata? Metadata is machine understandable information for the web W3C -- Metadata and Resource Description Metadata is structured information that is created specifically to describe another resource. In other words, metadata is 'data about data'. 4.8 Does the site work well in a range of browser window sizes? It is a common assumption amongst developers that average screen sizes are increasing. Some developers assume that the average screen size is now 1024px wide. But what about users with smaller screens and users with hand held devices? Are they part of your target audience and are they being disadvantaged? 5. Basic Usability 5.1 Is there a clear visual hierarchy? Organise and prioritise the contents of a page by using size, prominence and content relationships Create a Clear Visual Hierarchy 5.2 Are heading levels easy to distinguish? Use header elements to convey document structure and use them according to specification Web Content Accessibility Guidelines 1.0 -- checkpoint 3.5 5.3 Is the site's navigation easy to understand? Your navigation system should give your visitor a clue as to what page of the site they are currently on and where they can go next.[Design Tutorial -- Navigation]( http://www.1stsitefree.com/design nav.htm)_ 5.4 Is the site's navigation consistent? If each page on your site has a consistent style of presentation, visitors will find it easier to navigate between pages and find information Juicy studios -- Navigation 5.5 Does the site use consistent and appropriate language? The use of clear and simple language promotes effective communication. Trying to come across as articulate can be as difficult to read as poorly written grammar, especially if the language used isn't the visitor's primary language. Clear language 5.6 Does the site have a sitemap page and contact page? Are they easy to find? Most site maps fail to convey multiple levels of the site's information architecture. In usability tests, users often overlook site maps or can't find them. Complexity is also a problem: a map should be a map, not a navigational challenge of its own. Site Map Usability 5.7 For large sites, is there a search tool? While search tools are not needed on smaller sites, and some people will not ever use them, site-specific search tools allow users a choice of navigation options. 5.8 Is there a link to the home page on every page in the site? Some users like to go back to a site's home page after navigating to content within a site. The home page becomes a base camp for these users, allowing them to regroup before exploring new content. 5.9 Are links underlined? To maximise the perceived affordance of clickability, colour and underline the link text. Users shouldn't have to guess or scrub the page to find out where they can click. Guidelines for Visualizing Links 5.10 Are visited links clearly defined? Most important, knowing which pages they've already visited frees users from unintentionally revisiting the same pages over and over again. Change the Color of Visited Links 6. Site management 6.1 Does the site have a meaningful and helpful 404 error page that works from any depth in the site? You've requested a page -- either by typing a URL directly into the address bar or clicking on an out-of-date link and you've found yourself in the middle of cyberspace nowhere. A user-friendly website will give you a helping hand while many others will simply do nothing, relying on the browser's built-in ability to explain what the problem is. The perfect 404 6.2 Does the site use friendly URLs? Most search engines (with a few exceptions -- namely Google) will not index any pages that have a question mark or other character (like an ampersand or equals sign) in the URL... what good is a site if no one can find it? Search Engine-Friendly URLs One of the worst elements of the web from a user interface standpoint is the URL. However, if they're short, logical, and self-correcting, URLs can be acceptably usable How to make URLs user-friendly More: Creating Search Engine Friendly URLs How to make URLs user-friendly 6.3 Does the site's URL work without "www"? While this is not critical, and in some cases is not even possible, it is always good to give people the choice of both options. If a user types your domain name without the www and gets no site, this could disadvantage both the user and you. 6.4 Does the site have a favicon? A Favicon is a multi-resolution image included on nearly all professionally developed sites. The Favicon allows the webmaster to further promote their site, and to create a more customized appearance within a visitor's browser Favicon.com Favicons are definitely not critical. However, if they are not present, they can cause 404 errors in your logs (site statistics). Browsers like IE will request them from the server when a site is bookmarked. If a favicon isn't available, a 404 error may be generated. Therefore, having a favicon could cut down on favicon specific 404 errors. The same is true of a 'robots.txt' file.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu npm global or local packages The main difference between local and global packages is this: local packages are installed in the directory where you run npm install <package-name>, and they are put in the node_modules folder under this directory global packages are all put in a single place in your system (exactly where depends on your setup), regardless of where you run npm install -g <package-name> In your code you can only require local packages: so when should you install in one way or another? In general, all packages should be installed locally. This makes sure you can have dozens of applications in your computer, all running a different version of each package if needed. Updating a global package would make all your projects use the new release, and as you can imagine this might cause nightmares in terms of maintenance, as some packages might break compatibility with further dependencies, and so on. All projects have their own local version of a package, even if this might appear like a waste of resources, it's minimal compared to the possible negative consequences. A package should be installed globally when it provides an executable command that you run from the shell (CLI), and it's reused across projects. You can also install executable commands locally and run them using npx, but some packages are just better installed globally. Great examples of popular global packages which you might know are npm create-react-app vue-cli grunt-cli mocha react-native-cli gatsby-cli forever nodemon You probably have some packages installed globally already on your system. You can see them by running on your command line. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Firebase Understand Firebase projects Note: If you're using the Firebase Management REST API to programmatically create a Firebase project, you must first create a Google Cloud project, then add Firebase services to the existing project. Note: The project number and the project ID are the truly unique identifiers for a project across all of Firebase and Google Cloud. After Firebase provisions resources for a Firebase project, you cannot change its project ID. To use a specific identifier for Firebase resources, you must edit the project ID during the initial creation of the project. Caution: We do not recommend manually modifying an app's Firebase config file or object. If you initialize an app with invalid or missing values for any of these required "Firebase options", then your end users may experience serious issues. Note: For each Android app, if you provide a SHA-1 key for the app, you need to provide a package name and SHA-1 key combination that is globally unique across all of Google Cloud. This page offers brief overviews of several important concepts about Firebase projects. When available, follow the links to find more detailed information about features, services, and even other platforms. At the bottom of this page, find a listing of general best practices for Firebase projects. Relationship between Firebase projects, apps, and products A Firebase project is the top-level entity for Firebase. In a project, you create Firebase apps by registering your iOS, Android, or web apps. After you register your apps with Firebase, you can add the Firebase SDKs for any number of Firebase products, like Analytics, Cloud Firestore, Performance Monitoring, or Remote Config. Learn more detailed information about this process in the Getting Started guides ( iOS | Android | web | Unity | C++). Relationship between Firebase projects and Google Cloud When you create a new Firebase project in the Firebase console, you're actually creating a Google Cloud project behind the scenes. You can think of a Google Cloud project as a virtual container for data, code, configuration, and services. A Firebase project is a Google Cloud project that has additional Firebase-specific configurations and services. You can even create a Google Cloud project first, then add Firebase to the project later. Since a Firebase project is a Google Cloud project: Projects that appear in the Firebase console also appear in the Google Cloud Console and Google APIs console. Billing and permissions for projects are shared across Firebase and Google Cloud. Unique identifiers for a project (like the project number and the project ID) are shared across Firebase and Google Cloud. You can use products and APIs from both Firebase and Google Cloud in a project. Deleting a project deletes it across Firebase and Google Cloud. Setting up a Firebase project and registering apps You can set up a Firebase project and register apps in the Firebase console (or, for advanced use cases, via the Firebase Management REST API or the Firebase CLI). When you set up a project and register apps, you need to make some organizational decisions and add Firebase-specific configuration information to your local projects. Make sure to review some general project-level best practices (at the bottom of this page) before setting up a project and registering apps. The project name When you create a project, you provide a project name. This identifier is the internal-only name for a project in the Firebase console, the Google Cloud Console, and the Firebase CLI. The project name is not exposed in any publicly visible Firebase or Google Cloud product, service, or resource; it simply serves to help you more easily distinguish among multiple projects. You can edit a project name at any time in the settings Project settings of the Firebase console. The project name is displayed in the top pane. The project number A Firebase project (and its associated Google Cloud project) has a project number. This is the Google-assigned globally unique canonical identifier for the project. Use this identifier when configuring integrations and/or making API calls to Firebase, Google, or third-party services. API calls and the project number For many API calls, you need to include a unique identifier for a project. Although many APIs accept the project ID, it's recommended that you use the project number for making API calls to Firebase, Google, or third-party services. Learn more about using project identifiers, especially the project number, in Google's AIP 2510 standard. Find the project number Firebase console: Click settings Project settings. The project number is displayed in the top pane. Firebase CLI: Run firebase projects:list. The project number is displayed along with all the Firebase projects associated with your account. Firebase Management REST API: Call projects.list. The response body contains the project number in the FirebaseProject object. The project ID A Firebase project (and its associated Google Cloud project) has a project ID. This is a user-defined unique identifier for the project across all of Firebase and Google Cloud. When you create a Firebase project, Firebase automatically assigns a unique ID to the project, but you can edit it during project setup. This identifier should generally be treated as a convenience alias to reference the project. If you delete a project, the project ID is also deleted and can never be used again by any other project. Firebase resources and the project ID The project ID displays in publicly visible Firebase resources, for example: Default Hosting subdomain — PROJECT_ID.web.app and PROJECT_ID.firebaseapp.com Default Realtime Database URL — PROJECT_ID-default-rtdb.firebaseio.com or PROJECT_ID-default-rtdb. REGION_CODE.firebasedatabase.app Default Cloud Storage bucket name — PROJECT_ID.appspot.com For all of the aforementioned resources, you can create non-default instances. The publicly visible names of non-defaults are fully-customizable. You can connect custom domains to a Firebase-hosted site, shard the Realtime Database, and create multiple Cloud Storage buckets (visit the platform-specific Get Started page). The Firebase CLI and the project ID For some use cases, you might have multiple Firebase projects associated with the same local app directory. In these situations, when you use the Firebase CLI, you need to pass the --project flag with the firebase commands to communicate which Firebase project you want to interact with. You can also set up a project alias for each Firebase project so that you don't have to remember project IDs. API calls and the project ID For many API calls, you need to include a unique identifier for a project. Although many APIs accept the project ID, it's recommended that you use the project number for making API calls to Firebase, Google, or third-party services. Learn more about using project identifiers, especially the project number, in Google's AIP 2510 standard. Find the project ID Firebase console: Click settings Project settings. The project ID is displayed in the top pane. Firebase CLI: Run firebase projects:list. The project ID is displayed along with all the Firebase projects associated with your account. Firebase Management REST API: Call projects.list. The response body contains the project ID in the FirebaseProject object. Firebase config files and objects When you register an app with a Firebase project, the Firebase console provides a Firebase configuration file (iOS/Android apps) or a configuration object (web apps) that you add directly to your local app directory. For iOS apps, you add a GoogleService-Info.plist configuration file. For Android apps, you add a google-services.json configuration file. For web apps, you add a Firebase configuration object. At any time, you can obtain an app's Firebase config file or object. A Firebase config file or object associates an app with a specific Firebase project and its resources (databases, storage buckets, etc.). The configuration includes "Firebase options", which are parameters required by Firebase and Google services to communicate with Firebase server APIs and to associate client data with the Firebase project and Firebase app. Here are the required, minimum "Firebase options": API key: a simple encrypted string used when calling certain APIs that don't need to access private user data (example value: AIzaSyDOCAbC123dEf456GhI789jKl012-MnO) Project ID: a user-defined unique identifier for the project across all of Firebase and Google Cloud. This identifier may appear in URLs or names for some Firebase resources, but it should generally be treated as a convenience alias to reference the project. (example value: myapp-project-123) Application ID ("AppID"): the unique identifier for the Firebase app across all of Firebase with a platform-specific format: Firebase iOS apps: GOOGLE APP ID (example value: 1:1234567890:ios:321abc456def7890) This is not an Apple bundle ID. Firebase Android apps: mobilesdk app id (example value: 1:1234567890:android:321abc456def7890) This is not an Android package name or Android application ID. Firebase Web apps: appId (example value: 1:65211879909:web:3ae38ef1cdcb2e01fe5f0c) The content of the Firebase config file or object is considered public, including the app's platform-specific ID (iOS bundle ID or Android package name) and the Firebase project-specific values, like the API Key, project ID, Realtime Database URL, and Cloud Storage bucket name. Given this, use Firebase Security Rules to protect your data and files in Realtime Database, Cloud Firestore, and Cloud Storage. For open source projects, we generally do not recommend including the app's Firebase config file or object in source control because, in most cases, your users should create their own Firebase projects and point their apps to their own Firebase resources (via their own Firebase config file or object). Managing a Firebase project Make sure to review the general project-level best practices (at the bottom of this page) for considerations that might affect how you manage a Firebase project. Tools to manage a project Firebase console The Firebase console offers the richest environment for managing Firebase products, apps, and project-level settings. The left-side panel of the console lists the Firebase products, organized by top-level categories. At the top of the left-side panel, access a project's settings by clicking settings. A project's settings include integrations, access permissions, and billing. The middle of the console displays buttons that launch setup workflows to register various types of apps. After you start using Firebase, the main area of the console changes into a dashboard that displays stats on the products you use. Firebase CLI (a command line tool) Firebase also offers the Firebase CLI for configuring and managing specific Firebase products, like Firebase Hosting and Cloud Functions for Firebase. After installing the CLI, you have access to the global firebase command. Use the CLI to link your local app directory to a Firebase project, then deploy new versions of Firebase-hosted content or updates to functions. Firebase Management REST API Using the Firebase Management REST API, you can programmatically manage a Firebase project. For example, you can programmatically register an app with a project or list the apps that are already registered ( iOS | Android | web). General best practices Adding apps to a project Ensure that all apps within a project are platform variants of the same application from an end-user perspective. It's advisable to register the iOS, Android, and web versions of the same app or game with the same Firebase project. All the apps in a project generally share the same Firebase resources (database, storage buckets, etc.). If you have multiple build variants with different iOS bundle IDs or Android package names defined, you can register each variant with a separate Firebase project. However, if you have variants that share the same Firebase resources, register them with the same Firebase project. Here are some general limits for Firebase projects, apps, and sites: Number of projects per account Spark pricing plan — Project-creation quota is limited to a lower count of projects (usually around 5-10). Blaze pricing plan — Project-creation quota per account increases substantially as long as the associated Cloud Billing account is in good standing. The limit on project-creation quota is rarely a concern for most developers, but if needed, you can request an increase in project quota. Be aware that the complete deletion of a project requires 30 days and counts toward project quota until the project is fully deleted. Number of apps per project Firebase restricts the total number of Firebase Apps within a Firebase project to 30. You should ensure that all Firebase Apps within a single Firebase project are platform variants of the same application from an end-user perspective. Read more about best practices for multi-tenancy below. Learn more about the limit on apps per project in the FAQ. Number of Hosting sites per project The Firebase Hosting multisite feature supports a maximum of 36 sites per project. Multi-tenancy Connecting several different logically independent apps and/or web sites to a single Firebase project (often called "multi-tenancy") is not recommended. Multi-tenancy can lead to serious configuration and data privacy concerns problems, including unintended issues with analytics aggregation, shared authentication, overly-complex database structures, and difficulties with security rules. Generally, if a set of apps don't share the same data and configurations, strongly consider registering each app with a different Firebase project. For example, if you develop a white label application, each independently labelled app should have its own Firebase project, but the iOS and Android versions of that label can be in the same project. Each independently labeled app shouldn't (for privacy reasons) share data with the others. Launching your app Set up budget alerts for your project in the Google Cloud Console. Monitor the Usage and billing dashboard in the Firebase console to get an overall picture of your project's usage across multiple Firebase services. Review the Firebase launch checklist.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    The Uniform Resource Locator (URL) Let's look at the anatomy of a URL: The first part of the URL is http://, this is often left out when URLs are written, so we might see the above as www.mq.edu.au/about/profile/history.html. This will work when you type it into your web browser because the browser will assume you meant this as an HTTP URL. However, if we are being pedantic, the prefix is required as it tells us something about the web address - that we should use the HTTP protocol to access it. URLs are not only useful for HTTP addresses. Other schemes are allowed and they tell the client how to get access to the content that the URL describes. The most common you will see is https:// which is the secure variant of HTTP (we'll find out about that later). HTTPS uses the same protocol as HTTP but over a secure connection so that information that is exchanged can't be intercepted. Another scheme is ftp:// which tells the browser to use the older FTP protocol to access the content. Finally, you might see a mailto URL which allows us to write a link that triggers the browser to start composing an email message. This has a slightly different form: Steve.Cassidy@mq.edu.au but it's still a URL. In fact, the pattern looks like this: For the HTTP scheme the pattern is: The first part <net_loc> is the network location of the resource: the domain name of the web server that holds the web page we want. This is preceded by two forward slashes and followed by a single forward slash. Then follows the <path> which the server will use to identify which page we want. The ;<params>?<query>#<fragment> are used to further qualify the resource that we want; we'll see some examples of how they are used later in the book. The URL is a unique form of identifier in that it has two roles. First, it identifies a document, video or music file that's out on the web (we call these things resources). Each resource has a unique URL and you can refer to them via the URL. If we two people refer to the same URL, then they know they have read the same document. Secondly, the URL contains enough information for a web client to retrieve a copy of the resource. The client can use the scheme defined (HTTP) to connect to the server and send an HTTP request for the path part of the URL. There are other kinds of formal identifier that don't have this second property. For example, every book has an ISBN (International Standard Book Number) which uniquely identifies it. However, the ISBN contains no information about how to get a copy of the book. To do so, you'd need to look up the ISBN in a catalogue which might tell you who the publisher was and then contact them for a copy. Alternately you could go to a book-shop or library and use their catalogue to find the book. With a URL, there's no need for a catalogue or third party service to decode the identifier. The information on how to retrieve the resource is right there in the Uniform Resource Locator. The Internet Engineering Task Force (IETF) is as close as we get to a governing body for the Internet and it's home to many of the standards that define how the Internet and the Web work. The standards documents are called Request for Comments or RFC, a name which reflects the democratic nature of the early Internet. RFC2068 defines HTTP version 1.1 and RFC1738 defines the URL. Look out also for RFC2324 which can be relevant after a long coding session. Uniform Resource Identifiers There's another similar term that is sometimes used instead of URL: Uniform Resource Identifier (URI). URI is actually a more general term that includes URLs and Universal Resource Names (URNs). URNs are identifiers that don't contain any locator information such as the ISBN. They have a formal syntax so I can cite a particular ISBN as a URN as URN:ISBN:978-0-395-36341-6 (an example from the IETF RFC3187 document that defines the standard). As explained above, we need a third party service to resolve a URN into a real location (a URL). You might see the term URI used in discussions of web technologies; it is often used instead of URL but generally means the same thing if we're talking about HTTP based services. Since URLs are both names and addresses it becomes important that once you put a resource on the web, it stays there. This is discussed in Tim Berners-Lee's paper called " Cool URIs don't change". It's a principle that all web designers should bear in mind as it is easy to violate as we re-build old web-sites. Absolute and relative URLs When we include a URL in a web page there are a number of choices about how it can be written. The first option is to include the full URL: This is clearly a link to a resource on the server at example.org using the http protocol. However, if this page is being served by the server at example.org then we could also write this link as: This is known as a relative URL and is interpreted relative to the URL of the page that is currently being viewed. Let's assume that this page is at the URL http://example.org/about/info.html. Note that the URL above starts with a / character, in this case, the browser will interpret this URL by adding the protocol (http) and domain (example.org) parts of the page URL to this one to get http://example.org/static/style.css. Another way to write a URL is: In this case there is no / at the start of the URL and so this is interpreted relative to the page URL by removing everything but the last part of the URL http://example.org/about/ and then adding the new URL text to get http://example.org/about/static/style.css. Note that this is different to the previous example. If the intention was to reference the same URL as before, you could use the URL: Here the .. path refers to the parent directory (thinking of these paths as filenames) so the path becomes /about/../static/style.css which can be shortened to /static/style.css. The different URL styles have different uses. If you are writing a static HTML page that you will view on your local computer and perhaps host on the web somewhere (but you're not sure where) then you might put all of your files in one directory and use a relative URL like static/style.css to refer to linked resources. This ensures that your directory of files could be dropped anywhere into a web server file system and it would be self-contained and the links would work. However, if you are writing a web application that will be hosted on some domain (like example.org) you know that you have control of all URLs on that site and so would more likely use a relative URL starting with a / (like /static/style.css). This is important if your web application has complex routes (eg. pages like /users/steve/profile/edit) and you want to ensure that whatever the page URL being served, the links to stylesheets and other resources will work. The application can be deployed on different servers (like example.org and example.com) and the links will still work because they don't mention the domain name at all. Finally, absolute URLs (like http://example.org/static/style.css) will be used when we know that this URL is fixed at this location. It may be something external to our own site, or something that we know will be hosted at this URL on our site. There is an argument from a Search Engine Optimisation (SEO) viewpoint that all URLs in a website should be absolute urls even when they refer to assets on the same site. The reasons relate to the way that search engines crawl sites and the possible duplication of content if two URLs point to the same page (eg. https://example.org/ and http://example.org). One final form of relative URL looks like this: This URL is only missing the protocol part and is turned into an absolute URL by adding the protocol part of the current page URL. So if the current page was requested over http or https, this URL will use the same protocol. This is often useful if a site can be served over both protocols although it is increasingly the case that https is being used everywhere so this may become less common as time progresses. Share To Facebook:
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Semantic Versioning If there's one great thing in Node.js packages, it's that they all agreed on using Semantic Versioning for their version numbering. The Semantic Versioning concept is simple: all versions have 3 digits: x.y.z. the first digit is the major version the second digit is the minor version the third digit is the patch version When you make a new release, you don't just up a number as you please, but you have rules: you up the major version when you make incompatible API changes you up the minor version when you add functionality in a backward-compatible manner you up the patch version when you make backward-compatible bug fixes The convention is adopted all across programming languages, and it is very important that every npm package adheres to it, because the whole system depends on that. Why is that so important? Because npm set some rules we can use in the package.json file to choose which versions it can update our packages to, when we run npm update. The rules use those symbols:^~>>=<<==-|| Let's see those rules in detail:^: It will only do updates that do not change the leftmost non-zero number. If you write ^0.13.0, when running npm update, it can update to 0.13.1, 0.13.2, and so on, but not to 0.14.0 or above. If you write ^1.13.0, when running npm update, it can update to 1.13.1, 1.14.0 and so on, but will not update to 2.0.0 or above.~: if you write ~0.13.0, when running npm update it can update to patch releases: 0.13.1 is ok, but 0.14.0 is not.>: you accept any version higher than the one you specify>=: you accept any version equal to or higher than the one you specify<=: you accept any version equal or lower to the one you specify<: you accept any version lower to the one you specify=: you accept that exact version-: you accept a range of versions. Example: 2.1.0 - 2.6.2||: you combine sets. Example: < 2.1 || > 2.6 You can combine some of those notations, for example use 1.0.0 || >=1.1.0 <1.2.0 to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0. There are other rules, too: no symbol: you accept only that specific version you specify ( 1.2.1) latest: you want to use the latest version available Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Web Design Three different aspects of web site production: Content -- the text, images, etc. What the user wants to read. Style -- how the content is arranged on the page, fonts, colours, page style. Behaviour -- how users interact with the site, data processing, dynamic page elements. Since each requires different skills, a good (software) design would seperate them. Each of these areas has a different associated technology in the web world: HTML, Cascading Style Sheets (CSS) and Javascript. Note that it hasn't always been this way, HTML can do a bunch of Style things (eg. the <font> tag) but now that we have good standards compliant browser we don't need to use them. Document Production Moveable type, source Wikimedia Commons Many years ago, when printed pages were made with moveable type, the printer who assembled the page of type was responsible for all aspects of the page design. They would choose the typeface, and in the early days even make the matrix and cast the type themselves. They would lay out the lines of text, choosing suitable spacing in each line, deciding where to break the line and adding hyphens to improve the overall look of the page while maintaining readability. The page was then set in the press and pages were printed. Even before that, the monks who copied manuscripts did everything themselves, copying the text and adding beautiful illuminations to each page to add to the value of the book. As the industry developed though, the task of type-setter became more mechanical. Other people became expert in how to best lay out pages, what visual design elements would best communicate the desired message etc. The type-setter still made the technical choices to achieve the desired goals, but didn't have to be an expert in design. The production of a printed document would involve a number of people who were expert in their given area, from author to visual designer to type-setter. This team based approach to document production means that each person can develop their own expertise and to a certain extent, doesn't need to worry about what the people later in the chain will do. The author doesn't worry about how to place figures or images in the page, just that they will be there; the designer doesn't need to be concerned about kerning and the use of em-spaces in type-setting; the type-setter isn't an expert in the content of the text. All can work together to produce a superior printed document. The world of document production worked like this for a long time until the invention of the personal computer and Desktop Publishing software. Suddenly, authors became designers and type-setters through easy to use computer software. They could choose fonts, set margins, force hyphenation and make minute decisions about the layout and look and feel of each page. Not surprisingly, this becomes a significant distraction from the task of creating content, but it also means that the expertise of the specialist designer or type-setter isn't used any more. This might lead to more productivity as the production process is compressed, but it doesn't usually lead to more readable, better presented documents; many of the early self-produced documents were an unsightly mix of fonts, colours and sizes. If we fast-forward to the software tools we have today for document production, it's interesting to note that the expertise of the designer and typesetter has crept back in to the process. Rather than being involved in the production of every document, these people are now able to write stylesheets and templates as well as contribute to the algorithms used in the software to lay out the text on a page. Most companies will have a standard document template that is used for reports or letters, this has usually been designed by a professional and all the author needs to do is enter the text in the right place. Stylesheets in word processors mean that there will be a consistency of font use throughout the document and importantly, that the decisions on which fonts and how they are used doesn't need to be made by the author. So, to summarise this little discussion of history, there have always been people who's expertise is the way that a text is rendered on the page. With the onset of desktop publishing software, there has been a tendency for the author to spend time in document design, meaning that the relevant expertise was not being applied. However, modern software now allows for the designer's voice to be heard again through the use of stylesheets and document templates. This leaves the author to concentrate on the text meaning they will be more productive and should produce better looking documents as well. Web Document Production Fundamentally, the web is a technology for delivering content to readers through a document based interface (the web browser). So, producing web content is a document production process and as such, should parallel the ideas discussed above. It's interesting to look at the development of HTML and see how it parallels the developments described above. Early HTML was a language for encoding content. It included tags for headings, paragraphs, lists etc. but didn't provide any way to change the way these things were rendered by the browser. The browser made sensible decisions and web documents all looked about the same. The focus was on the content. Soon, graphical browsers started to appear that allowed images to be included in pages and people started to want to have some control over the appearance of their pages. The growth of the web into the commercial arena and the wider range of documents being published led to the 'browser wars' between Netscape and Microsoft. One of the features of this war was the arms race of features in each browser designed to make web pages look better. Each vendor would introduce new ways to control the look and feel of pages, for example the <FONT> tag was introduced by Netscape to allow control of the font used to display text while Microsoft included the <MARQUEE> tag that displayed text scrolling across the page. Eventually, some of these tags were standardised into a later version of HTML and were implemented by most of the browsers. These tags encouraged authors to get involved in page design, in fact they had to since the only way to control the appearance of a page was to insert codes into the text. While the <FONT> tag allowed some control over the appearance of text, there was still a problem of laying out a page as a whole. The solution that became standard practice was to mis-use the <TABLE> tag and construct the whole page as a table with rows and columns for the different page elements such as header, menu, content and footer. This worked really well, but again meant that the HTML code that an author was writing had to contain a lot of information about the layout of the page. In addition, it was common for people to mis-use tags just for the sake of appearance, for example to have more control over the appearance of headings, one might just encode them using <B> or <FONT> tags rather than header tags. All of these additions to HTML and the mis-use of existing tags meant that a language that was originally designed to allow authors to concentrate on content had turned into a page layout language. Luckily, sense has prevailed and we have now developed ways to control page layout without adding special instructions into the HTML code - that is, we have the Cascading Stylesheet language (CSS). Once again, we can let the author concentrate on content in HTML while all (or most) design decisions are encoded in the stylesheet. The current suite of web languages understood by your browser (HTML, CSS and Javascript) each serve different roles in the web development process: HTML - Content CSS - Style Javascript - Behaviour The third of these - Javascript and Behaviour - refer to the way that Javascript can be used to change the way that the user interacts with the page. This doesn't really have an analogue in the print document production world but it's an important aspect of modern web content production. It fits into this framework because the behavioural changes that Javascript can introduce should not be the concern of the content author or the visual designer (though both might have opinions on what they'd like to see). It is useful to think of these three aspects of web design as independent things. The same web content could be presented using alternate stylesheets and have a completely different impact. Similarly, Javascript can be used to change the way that a user interacts with content, making it more usable. We can see the Style and Behaviour aspects as layers that are applied to the core Content to enhance it for the user. The Separation of Concerns From a Computer Science/Software Engineering point of view there is a very important principle called the Separation of Concerns (SoC) that is illustrated perfectly by the way that the various web languages have evolved. The SoC principle is about partitioning the work that we do in software development into parts that can be considered separately. This is achieved by modularisation within a software project and is helped by things like classes and interface descriptions between modules in fact these things have been developed to support SoC. The SoC principle allows us to develop large complex software by allowing us to concentrate on different aspects of the solution. It could be that we do that alone, spending time on one aspect and then another, or as a team with different people assigned to different aspects. Either way, being able to work on part of the problem makes it manageable and improves the overall quality of the solution. In web development, the separation of concerns is supported by the different languages that work together to build a modern web application. It is important to recognise this and make sure that we use each of these tools in such a way as to respect their roles and capabilities. So, while it is possible to use HTML structures to make text large and bold for a heading, we don't, we use one of the header tags and rely on the stylesheet to apply the appropriate settings. Having the author respect good HTML usage means that the designer can make assumptions about the page structure in the stylesheet and ensure that the document appearance is consistent for the user. Semantic HTML Markup One corollary of this kind of thinking is that each component that we use should be used as it was designed and according to it's role in the overall picture. In particular for HTML this implies that the markup we use should encode only the structure of the document rather than aspects of the appearance which is properly dealt with using CSS. Further, this means that we should use markup in a way that imparts useful meaning to the document structure. This is generally known as using Semantic HTML ( Wikipedia, POSH on Microformats.org) and is the current best practice in HTML authoring. To clarify this point we can look at some examples. Writing semantic HTML means using the HTML tags as they were designed to be used - to convey the meaning of a particular document structure or textual element. So a good example is when we want to encode the main heading in a page I would use the H1 tag: This seems obvious, but in some cases, an author might decide that the default rendering of the H1 tag is too big, so rather than using CSS to define an alternate style, they use the H2 tag instead. This may seem harmless, after all we've still marked up this text as a heading. The problem is that we've lost the information that this is the main heading in the page that was conveyed by the H1 tag. Even worse, I could use the B (bold) tag and the now deprecated FONT tag to make my text look like a heading: In this case the appearance might be ok but the markup is not appropriate for the task. The author's focus has been on the appearance rather than the meaning of the markup; we could say that the author is overstepping their responsibilities a little - the appearance of the text should be the domain of the designer. If the heading is encoded as in this example, the designer will not be able to re-style the headings in a robust way (we could apply a style to bold paragraphs but that would also apply to any other use of this markup in the text). The example illustrates the importance of using an appropriate markup tag where one exists. In the case of a heading, this is pretty clear but other parts of the document might need a bit of thought to see what markup is appropriate. One common issue is whether to use a TABLE for some information that you want to appear as a list or array. TABLE is meant for data that has columns and rows, for example, the results of a survey or test scores for a class of students. While it is less common these days, the most frequent mis-use of tables is as a means of laying out all or part of a page as a rectangular grid. You may still see this in the navigation links on a page which the designer might want to appear in a row near the top of the page or a column down the side. Semantically this is a list and should really be marked up as such. If a table-like appearance is needed then CSS rules can be used to acheive this (eg. display: table-row). TABLE is sometimes used for things that might be more appropriately marked up as lists, eg. using UL (unordered list), OL (ordered list) or DL (description list) tags. An example might be the list of ingredients for a recipe; you might be tempted to encode it as a table because you want the quantities to be lined up in a column on the left. It might be appropriate to use TABLE here but a bit of reflection might tell you that it's really an unordered list - for example you might note that while there's usually a quantity for each ingredient it's not always the case ('salt to taste') so this isn't really columns of data, just list items that might have a distinguished field. A final example might be the description of a staff member in an online directory, the commonly contains entries for name, office, phone number, email address etc and it might seem natural to encode this as a table if you want a nice neat layout. However, in this case there is more appropriate markup in the DL (description list) tag. Each entry in a description list contains two parts DT (description title) and DD (description data) which are used to mark up the property name and value: Some authors are put off the description list because of the default style that is associated with it which puts the DT and DD parts on different lines. However, changing this is very easy with CSS so it really should be used for information that is structured in this way. Using the right semantic markup adds information to the text that can be used by the designer to enhance the communicative power of the web page. Using a consistent style for headings makes it easier for a reader to see the structure of a page and understand it. Similarly, I can use inline tags for things like emphasis (EM), Abbrv. (abbreviations, ABBR), “a quotation” (Q) or a strongly emphasised point (STRONG). Each of these has a default style (or in some cases like ABBR, is just the same as the default text style) but can be re-styled by the designer to achieve a particular look and feel. If these elements are used consistently throughout a text, the overall readability of the text can be greatly improved. Another motivation for using semantic markup is for users who cannot read via a normal web browser. Blind people make use software that reads out the content of a web page; if the page uses the appropriate semantic markup then the software can make use of this to present the content more appropriately to the user. This might include using the headings to provide a summary of the page or the emphasis tags to generate an appropriate intonation pattern. You might also think about the difference in reading out a list vs. a table of data - that might be a useful way of choosing between the two for a particular part of your page. Exercises Find an appropriate HTML tag to mark up the following items: the name of a book that you are citing in an essay a fragment of computer code, eg. a bit of Python an abbreviation or acronym and it's expansion (e.g. HTML - Hypertext Markup language) Extending the Semantics of HTML The tag set defined by the HTML standard supports a wide range of content and was designed to cover the most common document structures and entities that appear on the web. However, the designers of HTML couldn't forsee everything that you might want to mark in your documents and so an extension mechanism is included such that you can effectively add new semantics to existing tags. This is the HTML class attribute which allows you to enter a user defined class for any tag. It is effectively a specialisation of any tag that can be used to encode special meanings for your documents. The class attribute is meant to contain one or more class identifiers which are single words that mean something to your application. They can be applied to any HTML tag. An example might be the use of the class important to mark something as important in some way. I can add this to a paragraph or a list item: In this example, the class attribute is specialising the meaning of the main HTML tag so that we can differentiate important paragraphs and list items from others. We might want to do this so that we can highlight them in some way in the final presentation of the text. In this way, the designer can make the decision about how to emphasise this text (maybe differently on desktop and mobile devices) and the author is free just to decide which things are important. The alternative in this case might have been to use an emphasis EM tag around the text we wanted to emphasise. The advantage of the class attribute is that we identify the whole paragraph or list item as important and we are able to differentiate different kinds of emphasis. This might be useful where, for example, there are some things that are 'important' and others that are 'critical' in a set of instructions. The use of class attributes means that we can transfer the concepts that mean something in the domain of the document directly into the HTML code and then allow the designer to make decisions about how the different ideas are expressed visually. Sometimes there isn't an HTML tag that really fits what you are trying to express; in these cases you can use the generic DIV and SPAN tags along with a class attribute. For example, it has been common to use a series of DIV tags to denote the overall structure of a web page: This pattern allows the designer to write a stylesheet that places each section at the right place on the page with the right fonts, colours etc. This pattern has become so common that the new HTML5 standard has included new tags named after some of these classes, so you can now write: This is part of the evolution of the HTML language; the observation that some kinds of structure are being used very widely leading to the introduction of new elements that properly convey the semantics that are required. One final note about the use of classes to convey new semantics. It is possible to use more than one class name where that is appropriate to convey more specialisations. For example, all of the code examples in this text are marked up as PRE tags with the class code and another class to denote the language the code is written in, so on this page I have examples like: Note that I have to encode the HTML markup as entity references using the & notation so that they appear correctly when you view them in the web browser (view source to check this out). Having more than one class name means that I can apply standard styling to code examples and special style for different languages. It also means that I could write a script to pull out all of the examples in a given language if I wanted to check their syntax etc. A View of HTML Rather than being a chapter that will teach you the HTML language this will be a chapter about the language, how it works, why it has the structures it does and what you should and shouldn't do with it. Most people will know some HTML by now (assuming you've been studying computing for a while or have a general interest in the web). My task here is not to teach you HTML or act as a reference for the language, there are plenty of resources around that will do this. Some examples are: w3schools HTML tutorial w3schools is one of the most widely used tutorial and reference sites on the web for HTML and other web technologies. Learn HTML from the Mozilla Developer Network, the organisation that produces the Firefox browser. This page has pointers to a number of HTML tutorials and resources. About HTML HTML is a markup language, which is a formal language used to add encode structured documents, often by mixing formal elements and plain text. Another example is the LaTeX language used to typeset scientific and technical documents. Here's a fragment of LaTeX that shows the use of commands preceded by a backslash character and curly braces to enclose text: These commands are interpreted by the LaTeX system which uses then to produce nicely typeset PDF output. Markup can also be used to identify regions of text for analysis. Here's an example from a language corpus used to study human interaction: In this example, special character sequences are used to mark things like speaker turns, pauses, phrases and overlapping speech. This markup can be used to help analyse the language and find examples of certain linguistic phenomena (for example, find me examples of 'you know' and show me what the next person says in response). HTML is the Hypertext Markup Language, meaning that it is designed to encode hypertext documents - that is, documents containing links to other documents on the World Wide Web. In fact, the hyperlink is just a small part of HTML and much more interesting are all the other parts of the language that allows us to produce useful documents for the web. HTML is based on an earlier standard called SGML (Standard Generalised Markup language) which had a successor called XML (eXtensible Markup Language). SGML and XML are both languages for defining markup languages, that is they define the syntax of a markup language but allow you to develop your own language for a specific purpose. The syntax is the angle brackets containing start and end tags <p> and </p> that you will be familiar with (and a number of other rules). SGML and XML based languages all use this same syntax but allow the language designer to make up their own tags and define how they should be used together. HTML was designed originally by Tim Berners-Lee and later by the W3C as a language to encode pages of content for the web. Importantly, HTML is a markup language not a programming language. The job of a markup language is to record the structure of a document; that structure can then be interpreted by a program to generate some output. A programming language contains instructions that will be executed (or interpreted) to carry out some action or compute some result. Versions of HTML The first version of HTML was developed by Tim Berners-Lee as part of his World Wide Web project along with the HTTP protocol and the URL syntax. At first it was a very simple language for encoding articles and so had tags for headings, paragraphs, lists etc. Later, the language evolved to encompas new features in the browser such as the ability to display images, tables and modify the font that text was displayed in. The evolution of HTML has been quite gradual and at times part of intense competition between browser vendors (look up the Browser Wars to get the full story). The Internet Engineering Task Force (IETF) and later the World Wide Web Consortium (W3C) tried to standardise the language but it took some time for industry practice to align with the W3C standards. Luckily now we are in a period of relative stability where the standards process aligns well with what the major browsers are able to understand. A version of HTML is defined by a Document Type Definintion (DTD) - a formal definition of the allowed tags and attributes and the allowed structure of an HTML document. The DTD says that you can have a <p> tag and that it can contain a <strong> tag but that a <li> has to be inside a <ul> or <ol> tag and so on. If a document conforms to the DTD (follows the rules) we say that it is valid, if it contains errors such as having an unknown tag or a tag in the wrong place it is invalid. Early versions of HTML were subject to a lot of change and it wasn't until HTML version 4.0.1, released in 1999 that there was a bit of stability in the language and consensus about what should be included and what should be left out. Before then, HTML had grown to contain a lot of visual markup that had been developed by the browser vendors (Netscape and Microsoft) to try to make their browser look better than the competition. An example is the <font> tag introduced by Microsoft (and copied by Netscape) which could change the font used to render some text. By the time HTML 4.01 was published, Cascading Style Sheets (CSS) were becoming more widely adopted and the use of markup that explicitly referred to the visual appearance of the content was discouraged. HTML 4.0.1 is still the latest version of the official W3C standard although there have been a large number of changes implemented by the browser vendors since the time it was released. In 1997 the XML standard was introduced. XML was intended to generalise the use of markup on the web and allow developers to design thier own markup languages for specific purposes. XML is an evolution of the earlier SGML standard on which HTML had been based; it simplified the syntax rules a lot and made it easier to write parsers for XML. One of the early applications of XML was to develop XHTML - a version of HTML converted to adhere to the XML standard. XHTML 1.0 retained almost all of the tags in HTML 4.0.1 but introduced the constraints of XML. For example in an XML document every opening tag must have a corresponding close tag; in HTML, many close tags are optional (e.g. you can leave out the closing <p> tag for a paragraph since it is implied by the next opening <p> tag) and many tags never have a close tag because they never contain any text (e.g. <img> or <br>). In XHTML then, paragraphs always require a close tag and empty tags are written with the new XML syntax: <br />. One of the motivations for introducing XHTML was to try to encourage web developers to adhere more closely to the published standards. The web had grown up with a culture of view-source where people would learn how to encode web pages by looking at the source HTML of other web pages rather than by reading the standard. They would then write their own pages and if they looked ok in the browser, they would publish them. To cope with the amount of badly formed HTML content on the web, the browser vendors built thier HTML parsers to be very forgiving. If you put a paragraph inside an image tag or a header inside a paragraph it would have a go at rendering the content. As a consequence, very few web publishers cared about generating proper HTML and anyone who wanted to parse web content had to make very few assumptions about HTML structure. Around this time there was a move towards having more automated clients consuming web content. One group was the search engine developers who were just interested in the textual content of pages but other groups were trying to glean real data from the web. For example, price comparison services were starting up which tried to extract pricing information from store listings. Other services might try to find event information from web pages. All of these services needed to parse the HTML structure and had problems when the HTML was badly structured; this became known as Tag Soup since one could not rely on proper HTML structure it was just treated as an unstructured collection of tagged text. Permissive parsers such as Beautiful Soup (Python) and Tagsoup (Java) were developed to cope with the messy markup and give the developer as much detail as possible from the page. HTML5 The most recent version of HTML is HTML5 - note the name with no spaces which is quite different to earlier versions. HTML5 was a big change in the way that the standard was put together and followed a long break in the development of standards for HTML: HTML 4.0.1 was last updated in 2000, HTML5 was finally released in 2012. The goal of HTML5 was to standardise current practice in browsers, rather than to define new structures or limit what was possible. The W3C worked with the browser developers to agree on standards for new technologies that they had introduced. For example, being able to include audio and video elements in HTML had been possible in some browsers; HTML5 defined a standard for these that all browser vendors could agree on and implement.
    https://bgoonz-blog.netlify.app/images/code.png
  • Reading files
    Close Menu Reading Files The simplest way to read a file in Node.js is to use the fs.readFile() method, passing it the file path, encoding and a callback function that will be called with the file data (and the error): const fs = require('fs'); fs.readFile('/Users/joe/test.txt', 'utf8', (err, data) => { if (err) { console.error(err); return; } console.log(data); }); Alternatively, you can use the synchronous version fs.readFileSync(): const fs = require('fs'); try { const data = fs.readFileSync('/Users/joe/test.txt', 'utf8'); console.log(data); } catch (err) { console.error(err); } Both fs.readFile() and fs.readFileSync() read the full content of the file in memory before returning the data. This means that big files are going to have a major impact on your memory consumption and speed of execution of the program. In this case, a better option is to read the file content using streams. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    OS-Module This module provides many functions that you can use to retrieve information from the underlying operating system and the computer the program runs on, and interact with it. const os = require('os'); There are a few useful properties that tell us some key things related to handling files: os.EOL gives the line delimiter sequence. It's \n on Linux and macOS, and \r\n on Windows. os.constants.signals tells us all the constants related to handling process signals, like SIGHUP, SIGKILL and so on. os.constants.errno sets the constants for error reporting, like EADDRINUSE, EOVERFLOW and more. You can read them all on https://nodejs.org/api/os.html#os_signal_constants. Let's now see the main methods that os provides: os.arch() Return the string that identifies the underlying architecture, like arm, x64, arm64. os.cpus() Return information on the CPUs available on your system. Example:[ { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times: { user: 281685380, nice: 0, sys: 187986530, idle: 685833750, irq: 0 } }, { model: 'Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz', speed: 2400, times: { user: 282348700, nice: 0, sys: 161800480, idle: 703509470, irq: 0 } } ]; os.endianness() Return BE or LE depending if Node.js was compiled with Big Endian or Little Endian. os.freemem() Return the number of bytes that represent the free memory in the system. os.homedir() Return the path to the home directory of the current user. Example:'/Users/joe'; os.hostname() Return the host name. os.loadavg() Return the calculation made by the operating system on the load average. It only returns a meaningful value on Linux and macOS. Example:[3.68798828125, 4.00244140625, 11.1181640625]; os.networkInterfaces() Returns the details of the network interfaces available on your system. Example:{ lo0: [ { address: '127.0.0.1', netmask: '255.0.0.0', family: 'IPv4', mac: 'fe:82:00:00:00:00', internal: true }, { address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', family: 'IPv6', mac: 'fe:82:00:00:00:00', scopeid: 0, internal: true }, { address: 'fe80::1', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:82:00:00:00:00', scopeid: 1, internal: true } ], en1: [ { address: 'fe82::9b:8282:d7e6:496e', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: '06:00:00:02:0e:00', scopeid: 5, internal: false }, { address: '192.168.1.38', netmask: '255.255.255.0', family: 'IPv4', mac: '06:00:00:02:0e:00', internal: false } ], utun0: [ { address: 'fe80::2513:72bc:f405:61d0', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: 'fe:80:00:20:00:00', scopeid: 8, internal: false } ] } os.platform() Return the platform that Node.js was compiled for: darwin freebsd linux openbsd win32...more os.release() Returns a string that identifies the operating system release number os.tmpdir() Returns the path to the assigned temp folder. os.totalmem() Returns the number of bytes that represent the total memory available in the system. os.type() Identifies the operating system: Linux Darwin on macOS Windows_NT on Windows os.uptime() Returns the number of seconds the computer has been running since it was last rebooted. os.userInfo() Returns an object that contains the current username, uid, gid, shell, and homedir
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    The npx Node.js Package Runner NPX: npx is a very powerful command that's been available in npm starting version 5.2, released in July 2017. If you don't want to install npm, you can install npx as a standalone package npx lets you run code built with Node.js and published through the npm registry. Easily run local commands Node.js developers used to publish most of the executable commands as global packages, in order for them to be in the path and executable immediately. This was a pain because you could not really install different versions of the same command. Running npx commandname automatically finds the correct reference of the command inside the node_modules folder of a project, without needing to know the exact path, and without requiring the package to be installed globally and in the user's path. Installation-less command execution There is another great feature of npx, which is allowing to run commands without first installing them. This is pretty useful, mostly because: you don't need to install anything you can run different versions of the same command, using the syntax @version A typical demonstration of using npx is through the cowsay command. cowsay will print a cow saying what you wrote in the command. For example: cowsay "Hello" will print _______ < Hello > ------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || || This only works if you have the cowsay command globally installed from npm previously. Otherwise you'll get an error when you try to run the command. npx allows you to run that npm command without having it installed locally: npx cowsay "Hello" will do the job. Now, this is a funny useless command. Other scenarios include: running the vue CLI tool to create new applications and run them: npx @vue/cli create my-vue-app creating a new React app using create-react-app: npx create-react-app my-react-app and many more. Once downloaded, the downloaded code will be wiped. Run some code using a different Node.js version Use the @ to specify the version, and combine that with the node npm package: npx node@10 -v #v10.18.1 npx node@12 -v #v12.14.1 This helps to avoid tools like nvm or the other Node.js version management tools. Run arbitrary code snippets directly from a URL npx does not limit you to the packages published on the npm registry. You can run code that sits in a GitHub gist, for example: npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32 Of course, you need to be careful when running code that you do not control, as with great power comes great responsibility.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Introduction to npm Introduction to npm npm is the standard package manager for Node.js. In January 2017 over 350000 packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything. It started as a way to download and manage dependencies of Node.js packages, but it has since become a tool used also in frontend JavaScript. There are many things that npm does. Yarn is an alternative to npm. Make sure you check it out as well. Downloads npm manages downloads of dependencies of your project. Installing all dependencies If a project has a package.json file, by running npm install it will install everything the project needs, in the node_modules folder, creating it if it's not existing already. Installing a single package You can also install a specific package by running npm install <package-name> Often you'll see more flags added to this command:--save installs and adds the entry to the package.json file dependencies--save-dev installs and adds the entry to the package.json file devDependencies The difference is mainly that devDependencies are usually development tools, like a testing library, while dependencies are bundled with the app in production. Updating packages Updating is also made easy, by running npm update npm will check all packages for a newer version that satisfies your versioning constraints. You can specify a single package to update as well: npm update <package-name> Versioning In addition to plain downloads, npm also manages versioning, so you can specify any specific version of a package, or require a version higher or lower than what you need. Many times you'll find that a library is only compatible with a major release of another library. Or a bug in the latest release of a lib, still unfixed, is causing an issue. Specifying an explicit version of a library also helps to keep everyone on the same exact version of a package, so that the whole team runs the same version until the package.json file is updated. In all those cases, versioning helps a lot, and npm follows the semantic versioning (semver) standard. Running Tasks The package.json file supports a format for specifying command line tasks that can be run by using npm run <task-name> For example:{ "scripts": { "start-dev": "node lib/server-development", "start": "node lib/server-production" } } It's very common to use this feature to run Webpack:{ "scripts": { "watch": "webpack --watch --progress --colors --config webpack.conf.js", "dev": "webpack --progress --colors --config webpack.conf.js", "prod": "NODE_ENV=production webpack -p --config webpack.conf.js" } } So instead of typing those long commands, which are easy to forget or mistype, you can run$ npm run watch $ npm run dev $ npm run prod
    https://bgoonz-blog.netlify.app/images/code.png
  • Node vs Browser
    Close Menu Node vs Browser Both the browser and Node.js use JavaScript as their programming language. Building apps that run in the browser is a completely different thing than building a Node.js application. Despite the fact that it's always JavaScript, there are some key differences that make the experience radically different. From the perspective of a frontend developer who extensively uses JavaScript, Node.js apps bring with them a huge advantage: the comfort of programming everything - the frontend and the backend - in a single language. You have a huge opportunity because we know how hard it is to fully, deeply learn a programming language, and by using the same language to perform all your work on the web - both on the client and on the server, you're in a unique position of advantage. What changes is the ecosystem. In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies. Those do not exist in Node.js, of course. You don't have the document, window and all the other objects that are provided by the browser. And in the browser, we don't have all the nice APIs that Node.js provides through its modules, like the filesystem access functionality. Another big difference is that in Node.js you control the environment. Unless you are building an open source application that anyone can deploy anywhere, you know which version of Node.js you will run the application on. Compared to the browser environment, where you don't get the luxury to choose what browser your visitors will use, this is very convenient. This means that you can write all the modern ES6-7-8-9 JavaScript that your Node.js version supports. Since JavaScript moves so fast, but browsers can be a bit slow and users a bit slow to upgrade, sometimes on the web, you are stuck with using older JavaScript / ECMAScript releases. You can use Babel to transform your code to be ES5-compatible before shipping it to the browser, but in Node.js, you won't need that. Another difference is that Node.js uses the CommonJS module system, while in the browser we are starting to see the ES Modules standard being implemented. In practice, this means that for the time being you use require() in Node.js and import in the browser. Back to top
    https://bgoonz-blog.netlify.app/images/node.jpg
  • Javascript and Node
    Close Menu Javascript and Node As a beginner, it's hard to get to a point where you are confident enough in your programming abilities. While learning to code, you might also be confused at where does JavaScript end, and where Node.js begins, and vice versa. I would recommend you to have a good grasp of the main JavaScript concepts before diving into Node.js: Lexical Structure Expressions Types Variables Functions this Arrow Functions Loops Scopes Arrays Template Literals Semicolons Strict Mode ECMAScript 6, 2016, 2017 With those concepts in mind, you are well on your road to become a proficient JavaScript developer, in both the browser and in Node.js. The following concepts are also key to understand asynchronous programming, which is one fundamental part of Node.js: Asynchronous programming and callbacks Timers Promises Async and Await Closures The Event Loop Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu node-cli-args You can pass any number of arguments when invoking a Node.js application using Arguments can be standalone or have a key and a value. For example: or This changes how you will retrieve this value in the Node.js code. The way you retrieve it is using the process object built into Node.js. It exposes an argv property, which is an array that contains all the command line invocation arguments. The first element is the full path of the node command. The second element is the full path of the file being executed. All the additional arguments are present from the third position going forward. You can iterate over all the arguments (including the node path and the file path) using a loop: You can get only the additional arguments by creating a new array that excludes the first 2 params: If you have one argument without an index name, like this: you can access it using In this case: args[0] is name=joe, and you need to parse it. The best way to do so is by using the minimist library, which helps dealing with arguments: This time you need to use double dashes before each argument name: Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    The-package-lock.json-file The node command is the one we use to run our Node.js scripts: node script.js If we omit the filename, we use it in REPL mode: node Note: REPL also known as Read Evaluate Print Loop is a programming language environment(Basically a console window) that takes single expression as user input and returns the result back to the console after execution. If you try it now in your terminal, this is what happens:❯ node > the command stays in idle mode and waits for us to enter something. Tip: if you are unsure how to open your terminal, google "How to open terminal on <your-operating-system>". The REPL is waiting for us to enter some JavaScript code, to be more precise. Start simple and enter> console.log('test') test undefined > The first value, test, is the output we told the console to print, then we get undefined which is the return value of running console.log(). We can now enter a new line of JavaScript. Use the tab to autocomplete The cool thing about the REPL is that it's interactive. As you write your code, if you press the tab key the REPL will try to autocomplete what you wrote to match a variable you already defined or a predefined one. Exploring JavaScript objects Try entering the name of a JavaScript class, like Number, add a dot and press tab. The REPL will print all the properties and methods you can access on that class: Explore global objects You can inspect the globals you have access to by typing global. and pressing tab: The _ special variable If after some code you type _, that is going to print the result of the last operation. Dot commands The REPL has some special commands, all starting with a dot .. They are.help: shows the dot commands help.editor: enables editor mode, to write multiline JavaScript code with ease. Once you are in this mode, enter ctrl-D to run the code you wrote..break: when inputting a multi-line expression, entering the .break command will abort further input. Same as pressing ctrl-C..clear: resets the REPL context to an empty object and clears any multi-line expression currently being input..load: loads a JavaScript file, relative to the current working directory.save: saves all you entered in the REPL session to a file (specify the filename).exit: exits the repl (same as pressing ctrl-C two times) The REPL knows when you are typing a multi-line statement without the need to invoke .editor. For example if you start typing an iteration like this:[1, 2, 3].forEach(num => { and you press enter, the REPL will go to a new line that starts with 3 dots, indicating you can now continue to work on that block.... console.log(num) ... }) If you type .break at the end of a line, the multiline mode will stop and the statement will not be executed.
    https://bgoonz-blog.netlify.app/images/code.png
  • Sorting Algorithms
    Sorting Algorithms Sorting Algorithms Sorting Algorithms Explain the complexity of and write a function that performs bubble sort on an array of numbers. Time Complexity: O(n^2) In our worst case, our input is in the opposite order. We have to perform n swaps and loop through our input n times because a swap is made each time. Space Complexity: O(1) We are creating the same number of variables with an exact size, independent of our input. No new arrays are created. Code example for bubbleSort: function bubbleSort(array) { // We could have also had a 'sorted = false' flag and flipped our logic below let swapped = true; while (swapped) { swapped = false; for (let i = 0; i < array.length - 1; i++) { if (array[i] > array[i + 1]) { let temp = array[i]; array[i] = array[i + 1]; array[i + 1] = temp; // The above three lines could also be in a helper swap function // swap(array, i, i+1); swapped = true; } } } return array; } Explain the complexity of and write a function that performs selection sort on an array of numbers. Time Complexity: O(n^2) Our nested loop structure is dependent on the size of our input. The outer loop always occurs n times. For each of those iterations, we have another loop that runs (n - i) times. This just means that the inner loop runs one less time each iteration, but this averages out to (n/2). Our nested structure is then T(n * n/2) = O(n^2) Space Complexity: O(1) We are creating the same number of variables with an exact size, independent of our input. No new arrays are created. Code example for selectSort: function selectionSort(arr) { for (let i = 0; i < arr.length; i++) { let minIndex = i; for (let j = i + 1; j < arr.length; j++) { if (arr[minIndex] > arr[j]) { minIndex = j; } } let temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; // The above three lines could also be in a helper swap function // swap(arr, i, minIndex); } return arr; } Explain the complexity of and write a function that performs insertion sort on an array of numbers. Time Complexity: O(n^2) Our nested loop structure is dependent on the size of our input. The outer loop always occurs n times. For each of those iterations, we have another loop that runs a maximum of (i - 1) times. This just means that the inner loop runs one more time each iteration, but this averages out to (n/2). Our nested structure is then T(n * n/2) = O(n^2) Space Complexity: O(1) We are creating the same number of variables with an exact size, independent of our input. No new arrays are created. Code example for insertionSort: function insertionSort(arr) { for (let i = 1; i < arr.length; i++) { let currElement = arr[i]; for (var j = i - 1; j >= 0 && currElement < arr[j]; j--) { arr[j + 1] = arr[j]; } arr[j + 1] = currElement; } return arr; } Explain the complexity of and write a function that performs merge sort on an array of numbers. Time Complexity: O(n log n) Our mergeSort function divides our input in half at each step, recursively calling itself with smaller and smaller input. This results in log n stack frames. On each stack frame, our worst case scenario is having to make n comparisons in our merge function in order to determine which element should come next in our sorted array. Since we have log n stack frames and n operations on each frame, we end up with an O(n log n) time complexity Space Complexity: O(n) We are ultimately creating n subarrays, making our space complexity linear to our input size. Code example for mergeSort:// The merge function is what is combining our sorted sub-arrays function merge(array1, array2) { let merged = []; // keep running while either array still contains elements while (array1.length || array2.length) { // if array1 is nonempty, take its the first element as ele1 // otherwise array1 is empty, so take Infinity as ele1 let ele1 = array1.length ? array1[0] : Infinity; // do the same for array2, ele2 let ele2 = array2.length ? array2[0] : Infinity; let next; // remove the smaller of the eles from it's array if (ele1 < ele2) { next = array1.shift(); } else { next = array2.shift(); } // and add that ele to the new array merged.push(next); } return merged; } // The mergeSort function breaks apart our input into smaller sub-arrays until we have an input of length <= 1, which is inherently sorted. // Once we have a left and right subarray that's sorted, we can merge them together to get our sorted result of this sub-problem, passing the sorted version back up the call stack. function mergeSort(array) { if (array.length <= 1) { return array; } let midIdx = Math.floor(array.length / 2); let leftHalf = array.slice(0, midIdx); let rightHalf = array.slice(midIdx); let sortedLeft = mergeSort(leftHalf); let sortedRight = mergeSort(rightHalf); return merge(sortedLeft, sortedRight); } Explain the complexity of and write a function that performs quick sort on an array of numbers. Time Complexity: Average O(n log n), Worst O(n^2) In our worst case, the pivot that we select results in every element going into either the left or right array. If this happens we end up making n recursive calls to quickSort, with n comparisons at each call. In our average case, we pick something that more evenly splits the arrays, resulting in approximately log n recursive calls and an overall complexity of O(n log n). Quick sort is unique in that the worst case is so exceedingly rare that it is often considered an O(n log n) complexity, even though this is not technically accurate. Space Complexity: Our implementation O(n), Possible implementation O(log n) The partition arrays that we create are directly proportional to the size of the input, resulting in O(n) space complexity. With some tweaking, we could implement an in-place quick sort, which would eliminate the creation of new arrays. In this case, the log n stack frames from the recursion are the only proportional amount of space that is used, resulting in O(log n) space complexity. Code example for quickSort: function quickSort(array) { if (array.length <= 1) { return array; } let pivot = array.shift(); // This implementation uses filter, which returns a new array with any element that passes the criteria (ie the callback returns true). // We also could have iterated over the array (array.forEach(el => ...)) and pushed each value into the appropriate left/right subarray as we encountered it. let left = array.filter((el) => el < pivot); let right = array.filter((el) => el >= pivot); let leftSorted = quickSort(left); let rightSorted = quickSort(right); return [...leftSorted, pivot, ...rightSorted]; // We also could have concatenated the arrays instead of spreading their contents // return leftSorted.concat([pivot]).concat(rightSorted); } Explain the complexity of and write a function that performs a binary search on a sorted array of numbers. Time Complexity: O(log n) With each recursive call, we split our input in half. This means we have to make at most log n checks to know if the element is in our array. Space Complexity: Our implementation O(n), Possible implementation O(1) We have to make a subarray for each recursive call. In the worst case (we don't find the element), the total length of these arrays is approximately equal to the length of the original (n). If we kept references to the beginning and end index of the portion of the array that we are searching, we could eliminate the need for creating new subarrays. We could also use a while loop to perform this functionality until we either found our target or our beginning and end indices crossed. This would eliminate the space required for recursive calls (adding stack frames). Ultimately we would be using the same number of variables independent of input size, resulting in O(1). Code example for binarySearch and binarySearchIndex:// Returns simply true/false for presence function binarySearch(array, target) { if (array.length === 0) { return false; } let midIdx = Math.floor(array.length / 2); let leftHalf = array.slice(0, midIdx); let rightHalf = array.slice(midIdx + 1); if (target < array[midIdx]) { return binarySearch(leftHalf, target); } else if (target > array[midIdx]) { return binarySearch(rightHalf, target); } else { return true; } } // Returns the index or -1 if not found function binarySearchIndex(array, target) { if (!array.length) return -1; const midIdx = Math.floor(array.length / 2); const midEl = array[midIdx]; if (target < midEl) { return binarySearchIndex(array.slice(0, midIdx), target); } else if (target > midEl) { // Since our recursive call will have new indices for the subarray, we have to adjust the return value to align it with the indices of our original array. // If the recursive call returns -1, it was not found and we can immediately return -1 // If it was found in the subarray, we have to add on the number of elements that were removed from the beginning of our larger original array. // For example, if we try to find 15 in an array of [5, 10, 15]: // - Our first call to binarySearchIndex will check our middle element of 10 // - Since our target is greater, we will recursively call our search on elements to the right, being the subarray [15] // - On our recursive call we found our target! It's index in this call is 0. // - When we return 0 to where binarySearchIndex was called, we need to adjust it to line up with this larger array (the 0th element of this larger array is 5, but our target was at the 0th index of the subarray) // - Since we sliced off 2 elements from the beginning before making our recursive call, we add 2 to the return value to adjust it back to line up with our original array. const idxShift = binarySearchIndex(array.slice(midIdx + 1), target); return idxShift === -1 ? -1 : idxShift + midIdx + 1; } else { return midIdx; } }
    https://bgoonz-blog.netlify.app/images/image (9).png
  • Web-Dev-Hub
    packagejson If you work with JavaScript, or you've ever interacted with a JavaScript project, Node.js or a frontend project, you surely met the package.json file. What's that for? What should you know about it, and what are some of the cool things you can do with it? The package.json file is kind of a manifest for your project. It can do a lot of things, completely unrelated. It's a central repository of configuration for tools, for example. It's also where npm and yarn store the names and versions for all the installed packages. The file structure Here's an example package.json file: It's empty! There are no fixed requirements of what should be in a package.json file, for an application. The only requirement is that it respects the JSON format, otherwise it cannot be read by programs that try to access its properties programmatically. If you're building a Node.js package that you want to distribute over npm things change radically, and you must have a set of properties that will help other people use it. We'll see more about this later on. This is another package.json: It defines a name property, which tells the name of the app, or package, that's contained in the same folder where this file lives. Here's a much more complex example, which was extracted from a sample Vue.js application: there are lots of things going on here: version indicates the current version name sets the application/package name description is a brief description of the app/package main set the entry point for the application private if set to true prevents the app/package to be accidentally published on npm scripts defines a set of node scripts you can run dependencies sets a list of npm packages installed as dependencies devDependencies sets a list of npm packages installed as development dependencies engines sets which versions of Node.js this package/app works on browserslist is used to tell which browsers (and their versions) you want to support All those properties are used by either npm or other tools that we can use. Properties breakdown This section describes the properties you can use in detail. We refer to "package" but the same thing applies to local applications which you do not use as packages. Most of those properties are only used on https://www.npmjs.com/, others by scripts that interact with your code, like npm or others. name Sets the package name. Example: The name must be less than 214 characters, must not have spaces, it can only contain lowercase letters, hyphens (-) or underscores (_). This is because when a package is published on npm, it gets its own URL based on this property. If you published this package publicly on GitHub, a good value for this property is the GitHub repository name. author Lists the package author name Example: Can also be used with this format: contributors As well as the author, the project can have one or more contributors. This property is an array that lists them. Example: Can also be used with this format: bugs Links to the package issue tracker, most likely a GitHub issues page Example: homepage Sets the package homepage Example: version Indicates the current version of the package. Example: This property follows the semantic versioning (semver) notation for versions, which means the version is always expressed with 3 numbers: x.x.x. The first number is the major version, the second the minor version and the third is the patch version. There is a meaning in these numbers: a release that only fixes bugs is a patch release, a release that introduces backward-compatible changes is a minor release, a major release can have breaking changes. license Indicates the license of the package. Example: keywords This property contains an array of keywords that associate with what your package does. Example: This helps people find your package when navigating similar packages, or when browsing the https://www.npmjs.com/ website. description This property contains a brief description of the package Example: This is especially useful if you decide to publish your package to npm so that people can find out what the package is about. repository This property specifies where this package repository is located. Example: Notice the github prefix. There are other popular services baked in: You can explicitly set the version control system: You can use different version control systems: main Sets the entry point for the package. When you import this package in an application, that's where the application will search for the module exports. Example: private if set to true prevents the app/package to be accidentally published on npm Example: scripts Defines a set of node scripts you can run Example: These scripts are command line applications. You can run them by calling npm run XXXX or yarn XXXX, where XXXX is the command name. Example: npm run dev. You can use any name you want for a command, and scripts can do literally anything you want. dependencies Sets a list of npm packages installed as dependencies. When you install a package using npm or yarn: that package is automatically inserted in this list. Example: devDependencies Sets a list of npm packages installed as development dependencies. They differ from dependencies because they are meant to be installed only on a development machine, not needed to run the code in production. When you install a package using npm or yarn: that package is automatically inserted in this list. Example: engines Sets which versions of Node.js and other commands this package/app work on Example: browserslist Is used to tell which browsers (and their versions) you want to support. It's referenced by Babel, Autoprefixer, and other tools, to only add the polyfills and fallbacks needed to the browsers you target. Example: This configuration means you want to support the last 2 major versions of all browsers with at least 1% of usage (from the CanIUse.com stats), except IE8 and lower.( see more) Command-specific properties The package.json file can also host command-specific configuration, for example for Babel, ESLint, and more. Each has a specific property, like eslintConfig, babel and others. Those are command-specific, and you can find how to use those in the respective command/project documentation. Package versions You have seen in the description above version numbers like these: ~3.0.0 or ^0.13.0. What do they mean, and which other version specifiers can you use? That symbol specifies which updates your package accepts, from that dependency. Given that using semver (semantic versioning) all versions have 3 digits, the first being the major release, the second the minor release and the third is the patch release, you have these " Rules". You can combine most of the versions in ranges, like this: 1.0.0 || >=1.1.0 <1.2.0, to either use 1.0.0 or one release from 1.1.0 up, but lower than 1.2.0. Cheat Sheet:/* ******************************************************************************************* * SYNOPSIS * http://nodejs.org/api/synopsis.html * ******************************************************************************************* */ var http = require('http'); // An example of a web server written with Node which responds with 'Hello World'. // To run the server, put the code into a file called example.js and execute it with the node program. http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); }).listen(8124); console.log('Server running at http://127.0.0.1:8124/'); /* ******************************************************************************************* * GLOBAL OBJECTS * http://nodejs.org/api/globals.html * ******************************************************************************************* */ // In browsers, the top-level scope is the global scope. // That means that in browsers if you're in the global scope var something will define a global variable. // In Node this is different. The top-level scope is not the global scope; var something inside a Node module will be local to that module. __filename; // The filename of the code being executed. (absolute path) __dirname; // The name of the directory that the currently executing script resides in. (absolute path) module; // A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require(). exports; // A reference to the module.exports that is shorter to type. process; // The process object is a global object and can be accessed from anywhere. It is an instance of EventEmitter. Buffer; // The Buffer class is a global type for dealing with binary data directly. /* ******************************************************************************************* * CONSOLE * http://nodejs.org/api/console.html * ******************************************************************************************* */ console.log([data], [...]); // Prints to stdout with newline. console.info([data], [...]); // Same as console.log. console.error([data], [...]); // Same as console.log but prints to stderr. console.warn([data], [...]); // Same as console.error. console.dir(obj); // Uses util.inspect on obj and prints resulting string to stdout. console.time(label); // Mark a time. console.timeEnd(label); // Finish timer, record output. console.trace(label); // Print a stack trace to stderr of the current position. console.assert(expression, [message]); // Same as assert.ok() where if the expression evaluates as false throw an AssertionError with message. /* ******************************************************************************************* * TIMERS * http://nodejs.org/api/timers.html * ******************************************************************************************* */ setTimeout(callback, delay, [arg], [...]); // To schedule execution of a one-time callback after delay milliseconds. Optionally you can also pass arguments to the callback. clearTimeout(t); // Stop a timer that was previously created with setTimeout(). setInterval(callback, delay, [arg], [...]); // To schedule the repeated execution of callback every delay milliseconds. Optionally you can also pass arguments to the callback. clearInterval(t); // Stop a timer that was previously created with setInterval(). setImmediate(callback, [arg], [...]); // To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout and setInterval. clearImmediate(immediateObject); // Stop a timer that was previously created with setImmediate(). unref(); // Allow you to create a timer that is active but if it is the only item left in the event loop, node won't keep the program running. ref(); // If you had previously unref()d a timer you can call ref() to explicitly request the timer hold the program open. /* ******************************************************************************************* * MODULES * http://nodejs.org/api/modules.html * ******************************************************************************************* */ var module = require('./module.js'); // Loads the module module.js in the same directory. module.require('./another_module.js'); // load another_module as if require() was called from the module itself. module.id; // The identifier for the module. Typically this is the fully resolved filename. module.filename; // The fully resolved filename to the module. module.loaded; // Whether or not the module is done loading, or is in the process of loading. module.parent; // The module that required this one. module.children; // The module objects required by this one. exports.area = function (r) { return Math.PI * r * r; }; // If you want the root of your module's export to be a function (such as a constructor) // or if you want to export a complete object in one assignment instead of building it one property at a time, // assign it to module.exports instead of exports. module.exports = function(width) { return { area: function() { return width * width; } }; } /* ******************************************************************************************* * PROCESS * http://nodejs.org/api/process.html * ******************************************************************************************* */ process.on('exit', function(code) {}); // Emitted when the process is about to exit process.on('uncaughtException', function(err) {}); // Emitted when an exception bubbles all the way back to the event loop. (should not be used) process.stdout; // A writable stream to stdout. process.stderr; // A writable stream to stderr. process.stdin; // A readable stream for stdin. process.argv; // An array containing the command line arguments. process.env; // An object containing the user environment. process.execPath; // This is the absolute pathname of the executable that started the process. process.execArgv; // This is the set of node-specific command line options from the executable that started the process. process.arch; // What processor architecture you're running on: 'arm', 'ia32', or 'x64'. process.config; // An Object containing the JavaScript representation of the configure options that were used to compile the current node executable. process.pid; // The PID of the process. process.platform; // What platform you're running on: 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'. process.title; // Getter/setter to set what is displayed in 'ps'. process.version; // A compiled-in property that exposes NODE_VERSION. process.versions; // A property exposing version strings of node and its dependencies. process.abort(); // This causes node to emit an abort. This will cause node to exit and generate a core file. process.chdir(dir); // Changes the current working directory of the process or throws an exception if that fails. process.cwd(); // Returns the current working directory of the process. process.exit([code]); // Ends the process with the specified code. If omitted, exit uses the 'success' code 0. process.getgid(); // Gets the group identity of the process. process.setgid(id); // Sets the group identity of the process. process.getuid(); // Gets the user identity of the process. process.setuid(id); // Sets the user identity of the process. process.getgroups(); // Returns an array with the supplementary group IDs. process.setgroups(grps); // Sets the supplementary group IDs. process.initgroups(user, extra_grp); // Reads /etc/group and initializes the group access list, using all groups of which the user is a member. process.kill(pid, [signal]); // Send a signal to a process. pid is the process id and signal is the string describing the signal to send. process.memoryUsage(); // Returns an object describing the memory usage of the Node process measured in bytes. process.nextTick(callback); // On the next loop around the event loop call this callback. process.maxTickDepth; // Callbacks passed to process.nextTick will usually be called at the end of the current flow of execution, and are thus approximately as fast as calling a function synchronously. process.umask([mask]); // Sets or reads the process's file mode creation mask. process.uptime(); // Number of seconds Node has been running. process.hrtime(); // Returns the current high-resolution real time in a [seconds, nanoseconds] tuple Array. /* ******************************************************************************************* * CHILD PROCESS * http://nodejs.org/api/child_process.html * ******************************************************************************************* */ // Node provides a tri-directional popen facility through the child_process module. // It is possible to stream data through a child's stdin, stdout, and stderr in a fully non-blocking way. ChildProcess; // Class. ChildProcess is an EventEmitter. child.stdin; // A Writable Stream that represents the child process's stdin child.stdout; // A Readable Stream that represents the child process's stdout child.stderr; // A Readable Stream that represents the child process's stderr. child.pid; // The PID of the child process child.connected; // If .connected is false, it is no longer possible to send messages child.kill([signal]); // Send a signal to the child process child.send(message, [sendHandle]); // When using child_process.fork() you can write to the child using child.send(message, [sendHandle]) and messages are received by a 'message' event on the child. child.disconnect(); // Close the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. child_process.spawn(command, [args], [options]); // Launches a new process with the given command, with command line arguments in args. If omitted, args defaults to an empty Array. child_process.exec(command, [options], callback); // Runs a command in a shell and buffers the output. child_process.execFile(file, [args], [options], [callback]); // Runs a command in a shell and buffers the output. child_process.fork(modulePath, [args], [options]); // This is a special case of the spawn() functionality for spawning Node processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. /* ******************************************************************************************* * UTIL * http://nodejs.org/api/util.html * ******************************************************************************************* */ // These functions are in the module 'util'. Use require('util') to access them. util.format(format, [...]); // Returns a formatted string using the first argument as a printf-like format. (%s, %d, %j) util.debug(string); // A synchronous output function. Will block the process and output string immediately to stderr. util.error([...]); // Same as util.debug() except this will output all arguments immediately to stderr. util.puts([...]); // A synchronous output function. Will block the process and output all arguments to stdout with newlines after each argument. util.print([...]); // A synchronous output function. Will block the process, cast each argument to a string then output to stdout. (no newlines) util.log(string); // Output with timestamp on stdout. util.inspect(object, [opts]); // Return a string representation of object, which is useful for debugging. (options: showHidden, depth, colors, customInspect) util.isArray(object); // Returns true if the given "object" is an Array. false otherwise. util.isRegExp(object); // Returns true if the given "object" is a RegExp. false otherwise. util.isDate(object); // Returns true if the given "object" is a Date. false otherwise. util.isError(object); // Returns true if the given "object" is an Error. false otherwise. util.promisify(fn) // Takes a function whose last argument is a callback and returns a version that returns promises. util.inherits(constructor, superConstructor); // Inherit the prototype methods from one constructor into another. /* ******************************************************************************************* * EVENTS * http://nodejs.org/api/events.html * ******************************************************************************************* */ // All objects which emit events are instances of events.EventEmitter. You can access this module by doing: require("events"); // To access the EventEmitter class, require('events').EventEmitter. // All EventEmitters emit the event 'newListener' when new listeners are added and 'removeListener' when a listener is removed. emitter.addListener(event, listener); // Adds a listener to the end of the listeners array for the specified event. emitter.on(event, listener); // Same as emitter.addListener(). emitter.once(event, listener); // Adds a one time listener for the event. This listener is invoked only the next time the event is fired, after which it is removed. emitter.removeListener(event, listener); // Remove a listener from the listener array for the specified event. emitter.removeAllListeners([event]); // Removes all listeners, or those of the specified event. emitter.setMaxListeners(n); // By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. emitter.listeners(event); // Returns an array of listeners for the specified event. emitter.emit(event, [arg1], [arg2], [...]); // Execute each of the listeners in order with the supplied arguments. Returns true if event had listeners, false otherwise. EventEmitter.listenerCount(emitter, event); // Return the number of listeners for a given event. /* ******************************************************************************************* * STREAM * http://nodejs.org/api/stream.html * ******************************************************************************************* */ // A stream is an abstract interface implemented by various objects in Node. For example a request to an HTTP server is a stream, as is stdout. // Streams are readable, writable, or both. All streams are instances of EventEmitter. // The Readable stream interface is the abstraction for a source of data that you are reading from. // In other words, data comes out of a Readable stream. // A Readable stream will not start emitting data until you indicate that you are ready to receive it. // Examples of readable streams include: http responses on the client, http requests on the server, fs read streams // zlib streams, crypto streams, tcp sockets, child process stdout and stderr, process.stdin. var readable = getReadableStreamSomehow(); readable.on('readable', function() {}); // When a chunk of data can be read from the stream, it will emit a 'readable' event. readable.on('data', function(chunk) {}); // If you attach a data event listener, then it will switch the stream into flowing mode, and data will be passed to your handler as soon as it is available. readable.on('end', function() {}); // This event fires when there will be no more data to read. readable.on('close', function() {}); // Emitted when the underlying resource (for example, the backing file descriptor) has been closed. Not all streams will emit this. readable.on('error', function() {}); // Emitted if there was an error receiving data. // The read() method pulls some data out of the internal buffer and returns it. If there is no data available, then it will return null. // This method should only be called in non-flowing mode. In flowing-mode, this method is called automatically until the internal buffer is drained. readable.read([size]); readable.setEncoding(encoding); // Call this function to cause the stream to return strings of the specified encoding instead of Buffer objects. readable.resume(); // This method will cause the readable stream to resume emitting data events. readable.pause(); // This method will cause a stream in flowing-mode to stop emitting data events. readable.pipe(destination, [options]); // This method pulls all the data out of a readable stream, and writes it to the supplied destination, automatically managing the flow so that the destination is not overwhelmed by a fast readable stream. readable.unpipe([destination]); // This method will remove the hooks set up for a previous pipe() call. If the destination is not specified, then all pipes are removed. readable.unshift(chunk); // This is useful in certain cases where a stream is being consumed by a parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party. // The Writable stream interface is an abstraction for a destination that you are writing data to. // Examples of writable streams include: http requests on the client, http responses on the server, fs write streams, // zlib streams, crypto streams, tcp sockets, child process stdin, process.stdout, process.stderr. var writer = getWritableStreamSomehow(); writable.write(chunk, [encoding], [callback]); // This method writes some data to the underlying system, and calls the supplied callback once the data has been fully handled. writer.once('drain', write); // If a writable.write(chunk) call returns false, then the drain event will indicate when it is appropriate to begin writing more data to the stream. writable.end([chunk], [encoding], [callback]); // Call this method when no more data will be written to the stream. writer.on('finish', function() {}); // When the end() method has been called, and all data has been flushed to the underlying system, this event is emitted. writer.on('pipe', function(src) {}); // This is emitted whenever the pipe() method is called on a readable stream, adding this writable to its set of destinations. writer.on('unpipe', function(src) {}); // This is emitted whenever the unpipe() method is called on a readable stream, removing this writable from its set of destinations. writer.on('error', function(src) {}); // Emitted if there was an error when writing or piping data. // Duplex streams are streams that implement both the Readable and Writable interfaces. See above for usage. // Examples of Duplex streams include: tcp sockets, zlib streams, crypto streams. // Transform streams are Duplex streams where the output is in some way computed from the input. They implement both the Readable and Writable interfaces. See above for usage. // Examples of Transform streams include: zlib streams, crypto streams. /* ******************************************************************************************* * FILE SYSTEM * http://nodejs.org/api/fs.html * ******************************************************************************************* */ // To use this module do require('fs'). // All the methods have asynchronous and synchronous forms. fs.rename(oldPath, newPath, callback); // Asynchronous rename. No arguments other than a possible exception are given to the completion callback.Asynchronous ftruncate. No arguments other than a possible exception are given to the completion callback. fs.renameSync(oldPath, newPath); // Synchronous rename. fs.ftruncate(fd, len, callback); // Asynchronous ftruncate. No arguments other than a possible exception are given to the completion callback. fs.ftruncateSync(fd, len); // Synchronous ftruncate. fs.truncate(path, len, callback); // Asynchronous truncate. No arguments other than a possible exception are given to the completion callback. fs.truncateSync(path, len); // Synchronous truncate. fs.chown(path, uid, gid, callback); // Asynchronous chown. No arguments other than a possible exception are given to the completion callback. fs.chownSync(path, uid, gid); // Synchronous chown. fs.fchown(fd, uid, gid, callback); // Asynchronous fchown. No arguments other than a possible exception are given to the completion callback. fs.fchownSync(fd, uid, gid); // Synchronous fchown. fs.lchown(path, uid, gid, callback); // Asynchronous lchown. No arguments other than a possible exception are given to the completion callback. fs.lchownSync(path, uid, gid); // Synchronous lchown. fs.chmod(path, mode, callback); // Asynchronous chmod. No arguments other than a possible exception are given to the completion callback. fs.chmodSync(path, mode); // Synchronous chmod. fs.fchmod(fd, mode, callback); // Asynchronous fchmod. No arguments other than a possible exception are given to the completion callback. fs.fchmodSync(fd, mode); // Synchronous fchmod. fs.lchmod(path, mode, callback); // Asynchronous lchmod. No arguments other than a possible exception are given to the completion callback. fs.lchmodSync(path, mode); // Synchronous lchmod. fs.stat(path, callback); // Asynchronous stat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. fs.statSync(path); // Synchronous stat. Returns an instance of fs.Stats. fs.lstat(path, callback); // Asynchronous lstat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to. fs.lstatSync(path); // Synchronous lstat. Returns an instance of fs.Stats. fs.fstat(fd, callback); // Asynchronous fstat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd. fs.fstatSync(fd); // Synchronous fstat. Returns an instance of fs.Stats. fs.link(srcpath, dstpath, callback); // Asynchronous link. No arguments other than a possible exception are given to the completion callback. fs.linkSync(srcpath, dstpath); // Synchronous link. fs.symlink(srcpath, dstpath, [type], callback); // Asynchronous symlink. No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms) fs.symlinkSync(srcpath, dstpath, [type]); // Synchronous symlink. fs.readlink(path, callback); // Asynchronous readlink. The callback gets two arguments (err, linkString). fs.readlinkSync(path); // Synchronous readlink. Returns the symbolic link's string value. fs.unlink(path, callback); // Asynchronous unlink. No arguments other than a possible exception are given to the completion callback. fs.unlinkSync(path); // Synchronous unlink. fs.realpath(path, [cache], callback); // Asynchronous realpath. The callback gets two arguments (err, resolvedPath). fs.realpathSync(path, [cache]); // Synchronous realpath. Returns the resolved path. fs.rmdir(path, callback); // Asynchronous rmdir. No arguments other than a possible exception are given to the completion callback. fs.rmdirSync(path); // Synchronous rmdir. fs.mkdir(path, [mode], callback); // Asynchronous mkdir. No arguments other than a possible exception are given to the completion callback. mode defaults to 0777. fs.mkdirSync(path, [mode]); // Synchronous mkdir. fs.readdir(path, callback); // Asynchronous readdir. Reads the contents of a directory. The callback gets two arguments (err, files) where files is an array of the names of the files in the directory excluding '.' and '..'. fs.readdirSync(path); // Synchronous readdir. Returns an array of filenames excluding '.' and '..'. fs.close(fd, callback); // Asynchronous close. No arguments other than a possible exception are given to the completion callback. fs.closeSync(fd); // Synchronous close. fs.open(path, flags, [mode], callback); // Asynchronous file open. fs.openSync(path, flags, [mode]); // Synchronous version of fs.open(). fs.utimes(path, atime, mtime, callback); // Change file timestamps of the file referenced by the supplied path. fs.utimesSync(path, atime, mtime); // Synchronous version of fs.utimes(). fs.futimes(fd, atime, mtime, callback); // Change the file timestamps of a file referenced by the supplied file descriptor. fs.futimesSync(fd, atime, mtime); // Synchronous version of fs.futimes(). fs.fsync(fd, callback); // Asynchronous fsync. No arguments other than a possible exception are given to the completion callback. fs.fsyncSync(fd); // Synchronous fsync. fs.write(fd, buffer, offset, length, position, callback); // Write buffer to the file specified by fd. fs.writeSync(fd, buffer, offset, length, position); // Synchronous version of fs.write(). Returns the number of bytes written. fs.read(fd, buffer, offset, length, position, callback); // Read data from the file specified by fd. fs.readSync(fd, buffer, offset, length, position); // Synchronous version of fs.read. Returns the number of bytesRead. fs.readFile(filename, [options], callback); // Asynchronously reads the entire contents of a file. fs.readFileSync(filename, [options]); // Synchronous version of fs.readFile. Returns the contents of the filename. If the encoding option is specified then this function returns a string. Otherwise it returns a buffer. fs.writeFile(filename, data, [options], callback); // Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer. fs.writeFileSync(filename, data, [options]); // The synchronous version of fs.writeFile. fs.appendFile(filename, data, [options], callback); // Asynchronously append data to a file, creating the file if it not yet exists. data can be a string or a buffer. fs.appendFileSync(filename, data, [options]); // The synchronous version of fs.appendFile. fs.watch(filename, [options], [listener]); // Watch for changes on filename, where filename is either a file or a directory. The returned object is a fs.FSWatcher. The listener callback gets two arguments (event, filename). event is either 'rename' or 'change', and filename is the name of the file which triggered the event. fs.exists(path, callback); // Test whether or not the given path exists by checking with the file system. Then call the callback argument with either true or false. (should not be used) fs.existsSync(path); // Synchronous version of fs.exists. (should not be used) // fs.Stats: objects returned from fs.stat(), fs.lstat() and fs.fstat() and their synchronous counterparts are of this type. stats.isFile(); stats.isDirectory() stats.isBlockDevice() stats.isCharacterDevice() stats.isSymbolicLink() // (only valid with fs.lstat()) stats.isFIFO() stats.isSocket() fs.createReadStream(path, [options]); // Returns a new ReadStream object. fs.createWriteStream(path, [options]); // Returns a new WriteStream object. /* ******************************************************************************************* * PATH * http://nodejs.org/api/fs.html * ******************************************************************************************* */ // Use require('path') to use this module. // This module contains utilities for handling and transforming file paths. // Almost all these methods perform only string transformations. // The file system is not consulted to check whether paths are valid. path.normalize(p); // Normalize a string path, taking care of '..' and '.' parts. path.join([path1], [path2], [...]); // Join all arguments together and normalize the resulting path. path.resolve([from ...], to); // Resolves 'to' to an absolute path. path.relative(from, to); // Solve the relative path from 'from' to 'to'. path.dirname(p); // Return the directory name of a path. Similar to the Unix dirname command. path.basename(p, [ext]); // Return the last portion of a path. Similar to the Unix basename command. path.extname(p); // Return the extension of the path, from the last '.' to end of string in the last portion of the path. path.sep; // The platform-specific file separator. '\\' or '/'. path.delimiter; // The platform-specific path delimiter, ';' or ':'. /* ******************************************************************************************* * HTTP * http://nodejs.org/api/http.html * ******************************************************************************************* */ // To use the HTTP server and client one must require('http'). http.STATUS_CODES; // A collection of all the standard HTTP response status codes, and the short description of each. http.request(options, [callback]); // This function allows one to transparently issue requests. http.get(options, [callback]); // Set the method to GET and calls req.end() automatically. server = http.createServer([requestListener]); // Returns a new web server object. The requestListener is a function which is automatically added to the 'request' event. server.listen(port, [hostname], [backlog], [callback]); // Begin accepting connections on the specified port and hostname. server.listen(path, [callback]); // Start a UNIX socket server listening for connections on the given path. server.listen(handle, [callback]); // The handle object can be set to either a server or socket (anything with an underlying _handle member), or a {fd: <n>} object. server.close([callback]); // Stops the server from accepting new connections. server.setTimeout(msecs, callback); // Sets the timeout value for sockets, and emits a 'timeout' event on the Server object, passing the socket as an argument, if a timeout occurs. server.maxHeadersCount; // Limits maximum incoming headers count, equal to 1000 by default. If set to 0 - no limit will be applied. server.timeout; // The number of milliseconds of inactivity before a socket is presumed to have timed out. server.on('request', function (request, response) { }); // Emitted each time there is a request. server.on('connection', function (socket) { }); // When a new TCP stream is established. server.on('close', function () { }); // Emitted when the server closes. server.on('checkContinue', function (request, response) { }); // Emitted each time a request with an http Expect: 100-continue is received. server.on('connect', function (request, socket, head) { }); // Emitted each time a client requests a http CONNECT method. server.on('upgrade', function (request, socket, head) { }); // Emitted each time a client requests a http upgrade. server.on('clientError', function (exception, socket) { }); // If a client connection emits an 'error' event - it will forwarded here. request.write(chunk, [encoding]); // Sends a chunk of the body. request.end([data], [encoding]); // Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. request.abort(); // Aborts a request. request.setTimeout(timeout, [callback]); // Once a socket is assigned to this request and is connected socket.setTimeout() will be called. request.setNoDelay([noDelay]); // Once a socket is assigned to this request and is connected socket.setNoDelay() will be called. request.setSocketKeepAlive([enable], [initialDelay]); // Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called. request.on('response', function(response) { }); // Emitted when a response is received to this request. This event is emitted only once. request.on('socket', function(socket) { }); // Emitted after a socket is assigned to this request. request.on('connect', function(response, socket, head) { }); // Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed. request.on('upgrade', function(response, socket, head) { }); // Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed. request.on('continue', function() { }); // Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body. response.write(chunk, [encoding]); // This sends a chunk of the response body. If this merthod is called and response.writeHead() has not been called, it will switch to implicit header mode and flush the implicit headers. response.writeContinue(); // Sends a HTTP/1.1 100 Continue message to the client, indicating that the request body should be sent. response.writeHead(statusCode, [reasonPhrase], [headers]); // Sends a response header to the request. response.setTimeout(msecs, callback); // Sets the Socket's timeout value to msecs. If a callback is provided, then it is added as a listener on the 'timeout' event on the response object. response.setHeader(name, value); // Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here if you need to send multiple headers with the same name. response.getHeader(name); // Reads out a header that's already been queued but not sent to the client. Note that the name is case insensitive. response.removeHeader(name); // Removes a header that's queued for implicit sending. response.addTrailers(headers); // This method adds HTTP trailing headers (a header but at the end of the message) to the response. response.end([data], [encoding]); // This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, response.end(), MUST be called on each response. response.statusCode; // When using implicit headers (not calling response.writeHead() explicitly), this property controls the status code that will be sent to the client when the headers get flushed. response.headersSent; // Boolean (read-only). True if headers were sent, false otherwise. response.sendDate; // When true, the Date header will be automatically generated and sent in the response if it is not already present in the headers. Defaults to true. response.on('close', function () { }); // Indicates that the underlying connection was terminated before response.end() was called or able to flush. response.on('finish', function() { }); // Emitted when the response has been sent. message.httpVersion; // In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. message.headers; // The request/response headers object. message.trailers; // The request/response trailers object. Only populated after the 'end' event. message.method; // The request method as a string. Read only. Example: 'GET', 'DELETE'. message.url; // Request URL string. This contains only the URL that is present in the actual HTTP request. message.statusCode; // The 3-digit HTTP response status code. E.G. 404. message.socket; // The net.Socket object associated with the connection. message.setTimeout(msecs, callback); // Calls message.connection.setTimeout(msecs, callback). /* ******************************************************************************************* * URL * http://nodejs.org/api/url.html * ******************************************************************************************* */ // This module has utilities for URL resolution and parsing. Call require('url') to use it. url.parse(urlStr, [parseQueryString], [slashesDenoteHost]); // Take a URL string, and return an object. url.format(urlObj); // Take a parsed URL object, and return a formatted URL string. url.resolve(from, to); // Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. /* ******************************************************************************************* * QUERY STRING * http://nodejs.org/api/querystring.html * ******************************************************************************************* */ // This module provides utilities for dealing with query strings. Call require('querystring') to use it. querystring.stringify(obj, [sep], [eq]); // Serialize an object to a query string. Optionally override the default separator ('&') and assignment ('=') characters. querystring.parse(str, [sep], [eq], [options]); // Deserialize a query string to an object. Optionally override the default separator ('&') and assignment ('=') characters. /* ******************************************************************************************* * ASSERT * http://nodejs.org/api/assert.html * ******************************************************************************************* */ // This module is used for writing unit tests for your applications, you can access it with require('assert'). assert.fail(actual, expected, message, operator); // Throws an exception that displays the values for actual and expected separated by the provided operator. assert(value, message); assert.ok(value, [message]); // Tests if value is truthy, it is equivalent to assert.equal(true, !!value, message); assert.equal(actual, expected, [message]); // Tests shallow, coercive equality with the equal comparison operator ( == ). assert.notEqual(actual, expected, [message]); // Tests shallow, coercive non-equality with the not equal comparison operator ( != ). assert.deepEqual(actual, expected, [message]); // Tests for deep equality. assert.notDeepEqual(actual, expected, [message]); // Tests for any deep inequality. assert.strictEqual(actual, expected, [message]); // Tests strict equality, as determined by the strict equality operator ( === ) assert.notStrictEqual(actual, expected, [message]); // Tests strict non-equality, as determined by the strict not equal operator ( !== ) assert.throws(block, [error], [message]); // Expects block to throw an error. error can be constructor, RegExp or validation function. assert.doesNotThrow(block, [message]); // Expects block not to throw an error, see assert.throws for details. assert.ifError(value); // Tests if value is not a false value, throws if it is a true value. Useful when testing the first argument, error in callbacks. /* ******************************************************************************************* * OS * http://nodejs.org/api/os.html * ******************************************************************************************* */ // Provides a few basic operating-system related utility functions. // Use require('os') to access this module. os.tmpdir(); // Returns the operating system's default directory for temp files. os.endianness(); // Returns the endianness of the CPU. Possible values are "BE" or "LE". os.hostname(); // Returns the hostname of the operating system. os.type(); // Returns the operating system name. os.platform(); // Returns the operating system platform. os.arch(); // Returns the operating system CPU architecture. os.release(); // Returns the operating system release. os.uptime(); // Returns the system uptime in seconds. os.loadavg(); // Returns an array containing the 1, 5, and 15 minute load averages. os.totalmem(); // Returns the total amount of system memory in bytes. os.freemem(); // Returns the amount of free system memory in bytes. os.cpus(); // Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of milliseconds the CPU/core spent in: user, nice, sys, idle, and irq). os.networkInterfaces(); // Get a list of network interfaces. os.EOL; // A constant defining the appropriate End-of-line marker for the operating system. /* ******************************************************************************************* * BUFFER * http://nodejs.org/api/buffer.html * ******************************************************************************************* */ // Buffer is used to dealing with binary data // Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap Buffer.from(size); // Allocates a new buffer of size octets. Buffer.from(array); // Allocates a new buffer using an array of octets. Buffer.from(str, [encoding]); // Allocates a new buffer containing the given str. encoding defaults to 'utf8'. Buffer.isEncoding(encoding); // Returns true if the encoding is a valid encoding argument, or false otherwise. Buffer.isBuffer(obj); // Tests if obj is a Buffer Buffer.concat(list, [totalLength]); // Returns a buffer which is the result of concatenating all the buffers in the list together. Buffer.byteLength(string, [encoding]); // Gives the actual byte length of a string. buf.write(string, [offset], [length], [encoding]); // Writes string to the buffer at offset using the given encoding buf.toString([encoding], [start], [end]); // Decodes and returns a string from buffer data encoded with encoding (defaults to 'utf8') beginning at start (defaults to 0) and ending at end (defaults to buffer.length). buf.toJSON(); // Returns a JSON-representation of the Buffer instance, which is identical to the output for JSON Arrays buf.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd]); // Does copy between buffers. The source and target regions can be overlapped buf.slice([start], [end]); // Returns a new buffer which references the same memory as the old, but offset and cropped by the start (defaults to 0) and end (defaults to buffer.length) indexes. Negative indexes start from the end of the buffer. buf.fill(value, [offset], [end]); // Fills the buffer with the specified value buf[index]; // Get and set the octet at index buf.length; // The size of the buffer in bytes, Note that this is not necessarily the size of the contents buffer.INSPECT_MAX_BYTES; // How many bytes will be returned when buffer.inspect() is called. This can be overridden by user modules.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Node Export Module Node.js has a built-in module system. A Node.js file can import functionality exposed by other Node.js files. When you want to import something you use to import the functionality exposed in the library.js file that resides in the current file folder. In this file, functionality must be exposed before it can be imported by other files. Any other object or variable defined in the file by default is private and not exposed to the outer world. This is what the module.exports API offered by the module system allows us to do. When you assign an object or a function as a new exports property, that is the thing that's being exposed, and as such, it can be imported in other parts of your app, or in other apps as well. You can do so in 2 ways. The first is to assign an object to module.exports, which is an object provided out of the box by the module system, and this will make your file export just that object: The second way is to add the exported object as a property of exports. This way allows you to export multiple objects, functions or data: or directly And in the other file, you'll use it by referencing a property of your import: or What's the difference between module.exports and exports? The first exposes the object it points to. The latter exposes the properties of the object it points to. Back to top
    https://bgoonz-blog.netlify.app/images/cool-comet.png
  • Web-Dev-Hub
    Common Modules Modules: CommonJS modules Stability: 2 - Stable In the Node.js module system, each file is treated as a separate module. For example, consider a file named foo.js: const circle = require('./circle.js'); console.log(`The area of a circle of radius 4 is ${circle.area(4)}`); On the first line, foo.js loads the module circle.js that is in the same directory as foo.js. Here are the contents of circle.js: const { PI } = Math; exports.area = (r) => PI * r ** 2; exports.circumference = (r) => 2 * PI * r; The module circle.js has exported the functions area() and circumference(). Functions and objects are added to the root of a module by specifying additional properties on the special exports object. Variables local to the module will be private, because the module is wrapped in a function by Node.js (see module wrapper). In this example, the variable PI is private to circle.js. The module.exports property can be assigned a new value (such as a function or object). Below, bar.js makes use of the square module, which exports a Square class: const Square = require('./square.js'); const mySquare = new Square(2); console.log(`The area of mySquare is ${mySquare.area()}`); The square module is defined in square.js:// Assigning to exports will not modify module, must use module.exports module.exports = class Square { constructor(width) { this.width = width; } area() { return this.width ** 2; } }; The module system is implemented in the require('module') module. Accessing the main module When a file is run directly from Node.js, require.main is set to its module. That means that it is possible to determine whether a file has been run directly by testing require.main === module. For a file foo.js, this will be true if run via node foo.js, but false if run by require('./foo'). Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename. Package manager tips The semantics of the Node.js require() function were designed to be general enough to support reasonable directory structures. Package manager programs such as dpkg, rpm, and npm will hopefully find it possible to build native packages from Node.js modules without modification. Below we give a suggested directory structure that could work: Let's say that we wanted to have the folder at /usr/lib/node/<some-package>/<some-version> hold the contents of a specific version of a package. Packages can depend on one another. In order to install package foo, it may be necessary to install a specific version of package bar. The bar package may itself have dependencies, and in some cases, these may even collide or form cyclic dependencies. Because Node.js looks up the realpath of any modules it loads (that is, it resolves symlinks) and then looks for their dependencies in node_modules folders, this situation can be resolved with the following architecture:/usr/lib/node/foo/1.2.3/: Contents of the foo package, version 1.2.3./usr/lib/node/bar/4.3.2/: Contents of the bar package that foo depends on./usr/lib/node/foo/1.2.3/node_modules/bar: Symbolic link to /usr/lib/node/bar/4.3.2/./usr/lib/node/bar/4.3.2/node_modules/*: Symbolic links to the packages that bar depends on. Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use. When the code in the foo package does require('bar'), it will get the version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar. Then, when the code in the bar package calls require('quux'), it'll get the version that is symlinked into /usr/lib/node/bar/4.3.2/node_modules/quux. Furthermore, to make the module lookup process even more optimal, rather than putting packages directly in /usr/lib/node, we could put them in /usr/lib/node_modules/<name>/<version>. Then Node.js will not bother looking for missing dependencies in /usr/node_modules or /node_modules. In order to make modules available to the Node.js REPL, it might be useful to also add the /usr/lib/node_modules folder to the $NODE_PATH environment variable. Since the module lookups using node_modules folders are all relative, and based on the real path of the files making the calls to require(), the packages themselves can be anywhere. The extension# It is not possible to require() files that have the .mjs extension. Attempting to do so will throw an error. The .mjs extension is reserved for ECMAScript Modules which cannot be loaded via require(). See ECMAScript Modules for more details. All together... To get the exact filename that will be loaded when require() is called, use the require.resolve() function. Putting together all of the above, here is the high-level algorithm in pseudocode of what require() does: require(X) from module at path Y If X is a core module, a. return the core module b. STOP If X begins with '/' a. set Y to be the filesystem root If X begins with './' or '/' or '../' a. LOAD AS FILE(Y + X) b. LOAD AS DIRECTORY(Y + X) c. THROW "not found" If X begins with '#' a. LOAD PACKAGE IMPORTS(X, dirname(Y)) LOAD PACKAGE SELF(X, dirname(Y)) LOAD NODE MODULES(X, dirname(Y)) THROW "not found" LOAD AS FILE(X) If X is a file, load X as its file extension format. STOP If X.js is a file, load X.js as JavaScript text. STOP If X.json is a file, parse X.json to a JavaScript Object. STOP If X.node is a file, load X.node as binary addon. STOP LOAD_INDEX(X) If X/index.js is a file, load X/index.js as JavaScript text. STOP If X/index.json is a file, parse X/index.json to a JavaScript object. STOP If X/index.node is a file, load X/index.node as binary addon. STOP LOAD AS DIRECTORY(X) If X/package.json is a file, a. Parse X/package.json, and look for "main" field. b. If "main" is a falsy value, GOTO 2. c. let M = X + (json main field) d. LOAD AS FILE(M) e. LOAD INDEX(M) f. LOAD INDEX(X) DEPRECATED g. THROW "not found" LOAD_INDEX(X) LOAD NODE MODULES(X, START) let DIRS = NODE MODULES PATHS(START) for each DIR in DIRS: a. LOAD PACKAGE EXPORTS(X, DIR) b. LOAD AS FILE(DIR/X) c. LOAD AS DIRECTORY(DIR/X) NODE MODULES PATHS(START) let PARTS = path split(START) let I = count of PARTS - 1 let DIRS = [GLOBAL_FOLDERS] while I >= 0, a. if PARTS[I] = "node modules" CONTINUE b. DIR = path join(PARTS[0 .. I] + "node modules") c. DIRS = DIRS + DIR d. let I = I - 1 return DIRS LOAD PACKAGE IMPORTS(X, DIR) Find the closest package scope SCOPE to DIR. If no scope was found, return. If the SCOPE/package.json "imports" is null or undefined, return. let MATCH = PACKAGE IMPORTS RESOLVE(X, pathToFileURL(SCOPE), ["node", "require"]) defined in the ESM resolver. RESOLVE ESM MATCH(MATCH). LOAD PACKAGE EXPORTS(X, DIR) Try to interpret X as a combination of NAME and SUBPATH where the name may have a @scope/ prefix and the subpath begins with a slash (/). If X does not match this pattern or DIR/NAME/package.json is not a file, return. Parse DIR/NAME/package.json, and look for "exports" field. If "exports" is null or undefined, return. let MATCH = PACKAGE EXPORTS RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, package.json "exports", ["node", "require"]) defined in the ESM resolver. RESOLVE ESM MATCH(MATCH) LOAD PACKAGE SELF(X, DIR) Find the closest package scope SCOPE to DIR. If no scope was found, return. If the SCOPE/package.json "exports" is null or undefined, return. If the SCOPE/package.json "name" is not the first segment of X, return. let MATCH = PACKAGE EXPORTS RESOLVE(pathToFileURL(SCOPE), "." + X.slice("name".length), package.json "exports", ["node", "require"]) defined in the ESM resolver. RESOLVE ESM MATCH(MATCH) RESOLVE ESM MATCH(MATCH) let { RESOLVED, EXACT } = MATCH let RESOLVED_PATH = fileURLToPath(RESOLVED) If EXACT is true, a. If the file at RESOLVED PATH exists, load RESOLVED PATH as its extension format. STOP Otherwise, if EXACT is false, a. LOAD AS FILE(RESOLVED PATH) b. LOAD AS DIRECTORY(RESOLVED PATH) THROW "not found" Caching Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file. Provided require.cache is not modified, multiple calls to require('foo') will not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles. To have a module execute code multiple times, export a function, and call that function. Module caching caveats Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files. Additionally, on case-insensitive file systems or operating systems, different resolved filenames can point to the same file, but the cache will still treat them as different modules and will reload the file multiple times. For example, require('./foo') and require('./FOO') return two different objects, irrespective of whether or not ./foo and ./FOO are the same file. Core modules History Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation. The core modules are defined within the Node.js source and are located in the lib/ folder. Core modules are always preferentially loaded if their identifier is passed to require(). For instance, require('http') will always return the built in HTTP module, even if there is a file by that name. Core modules can also be identified using the node: prefix, in which case it bypasses the require cache. For instance, require('node:http') will always return the built in HTTP module, even if there is require.cache entry by that name. Cycles When there are circular require() calls, a module might not have finished executing when it is returned. Consider this situation: a.js: console.log('a starting'); exports.done = false; const b = require('./b.js'); console.log('in a, b.done = %j', b.done); exports.done = true; console.log('a done'); b.js: console.log('b starting'); exports.done = false; const a = require('./a.js'); console.log('in b, a.done = %j', a.done); exports.done = true; console.log('b done'); main.js: console.log('main starting'); const a = require('./a.js'); const b = require('./b.js'); console.log('in main, a.done = %j, b.done = %j', a.done, b.done); When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module. By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:$ node main.js main starting a starting b starting in b, a.done = false b done in a, b.done = true a done in main, a.done = true, b.done = true Careful planning is required to allow cyclic module dependencies to work correctly within an application. File modules If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js, .json, and finally .node..js files are interpreted as JavaScript text files, and .json files are parsed as JSON text files. .node files are interpreted as compiled addon modules loaded with process.dlopen(). A required module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js. A required module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it. Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder. If the given path does not exist, require() will throw an Error with its code property set to 'MODULE_NOT_FOUND'. Folders as modules It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to those directories. There are three ways in which a folder may be passed to require() as an argument. The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:{ "name" : "some-library", "main" : "./lib/some-library.js" } If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js. This is the extent of the awareness of package.json files within Node.js. If there is no package.json file present in the directory, or if the "main" entry is missing or cannot be resolved, then Node.js will attempt to load an index.js or index.node file out of that directory. For example, if there was no package.json file in the previous example, then require('./some-library') would attempt to load:./some-library/index.js./some-library/index.node If these attempts fail, then Node.js will report the entire module as missing with the default error: Error: Cannot find module 'some-library' Loading from folders# If the module identifier passed to require() is not a core module, and does not begin with '/', '../', or './', then Node.js starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node.js will not append node_modules to a path already ending in node_modules. If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached. For example, if the file at '/home/ry/projects/foo.js' called require('bar.js'), then Node.js would look in the following locations, in this order:/home/ry/projects/node_modules/bar.js/home/ry/node_modules/bar.js/home/node_modules/bar.js/node_modules/bar.js This allows programs to localize their dependencies, so that they do not clash. It is possible to require specific files or sub modules distributed with a module by including a path suffix after the module name. For instance require('example-module/path/to/file') would resolve path/to/file relative to where example-module is located. The suffixed path follows the same module resolution semantics. Loading from the global folders If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere. On Windows, NODE_PATH is delimited by semicolons (;) instead of colons. NODE_PATH was originally created to support loading modules from varying paths before the current module resolution algorithm was defined. NODE_PATH is still supported, but is less necessary now that the Node.js ecosystem has settled on a convention for locating dependent modules. Sometimes deployments that rely on NODE_PATH show surprising behavior when people are unaware that NODE_PATH must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the NODE_PATH is searched. Additionally, Node.js will search in the following list of GLOBAL_FOLDERS: 1: $HOME/.node_modules 2: $HOME/.node_libraries 3: $PREFIX/lib/node Where $HOME is the user's home directory, and $PREFIX is the Node.js configured node_prefix. These are mostly for historic reasons. It is strongly encouraged to place dependencies in the local node_modules folder. These will be loaded faster, and more reliably. The module wrapper Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:(function(exports, require, module, __filename, __dirname) { // Module code actually lives in here }); By doing this, Node.js achieves a few things: It keeps top-level variables (defined with var, const or let) scoped to the module rather than the global object. It helps to provide some global-looking variables that are actually specific to the module, such as: The module and exports objects that the implementor can use to export values from the module. The convenience variables __filename and __dirname, containing the module's absolute filename and directory path. The module scope# Added in: v0.1.27 The directory name of the current module. This is the same as the path.dirname() of the __filename. Example: running node example.js from /Users/mjr console.log(__dirname); // Prints: /Users/mjr console.log(path.dirname(__filename)); // Prints: /Users/mjr # Added in: v0.0.1 The file name of the current module. This is the current module file's absolute path with symlinks resolved. For a main program this is not necessarily the same as the file name used in the command line. See __dirname for the directory name of the current module. Examples: Running node example.js from /Users/mjr console.log(__filename); // Prints: /Users/mjr/example.js console.log(__dirname); // Prints: /Users/mjr Given two modules: a and b, where b is a dependency of a and there is a directory structure of:/Users/mjr/app/a.js/Users/mjr/app/node_modules/b/b.js References to __filename within b.js will return /Users/mjr/app/node_modules/b/b.js while references to __filename within a.js will return /Users/mjr/app/a.js.# Added in: v0.1.12 A reference to the module.exports that is shorter to type. See the section about the exports shortcut for details on when to use exports and when to use module.exports.# Added in: v0.1.16 A reference to the current module, see the section about the module object. In particular, module.exports is used for defining what a module exports and makes available through require().# Added in: v0.1.13 id module name or path Returns: exported module content Used to import modules, JSON, and local files. Modules can be imported from node_modules. Local modules and JSON files can be imported using a relative path (e.g. ./, ./foo, ./bar/baz, ../foo) that will be resolved against the directory named by __dirname (if defined) or the current working directory. The relative paths of POSIX style are resolved in an OS independent fashion, meaning that the examples above will work on Windows in the same way they would on Unix systems.// Importing a local module with a path relative to the `__dirname` or current // working directory. (On Windows, this would resolve to .\path\myLocalModule.) const myLocalModule = require('./path/myLocalModule'); // Importing a JSON file: const jsonData = require('./path/filename.json'); // Importing a module from node_modules or Node.js built-in module: const crypto = require('crypto'); # Added in: v0.3.0 Modules are cached in this object when they are required. By deleting a key value from this object, the next require will reload the module. This does not apply to native addons, for which reloading will result in an error. Adding or replacing entries is also possible. This cache is checked before native modules and if a name matching a native module is added to the cache, only node:-prefixed require calls are going to receive the native module. Use with care! const assert = require('assert'); const realFs = require('fs'); const fakeFs = {}; require.cache.fs = { exports: fakeFs }; assert.strictEqual(require('fs'), fakeFs); assert.strictEqual(require('node:fs'), realFs); # Added in: v0.3.0Deprecated since: v0.10.6 Stability: 0 - Deprecated Instruct require on how to handle certain file extensions. Process files with the extension .sjs as .js: require.extensions['.sjs'] = require.extensions['.js']; Deprecated. In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time. Avoid using require.extensions. Use could cause subtle bugs and resolving the extensions gets slower with each registered extension.# Added in: v0.1.17 The Module object representing the entry script loaded when the Node.js process launched. See "Accessing the main module". In entry.js script: console.log(require.main); node entry.js Module { id: '.', path: '/absolute/path/to', exports: {}, filename: '/absolute/path/to/entry.js', loaded: false, children: [], paths: [ '/absolute/path/to/node_modules', '/absolute/path/node_modules', '/absolute/node_modules', '/node_modules' ] } # History request The module path to resolve. options paths <string[]> Paths to resolve module location from. If present, these paths are used instead of the default resolution paths, with the exception of GLOBAL_FOLDERS like $HOME/.node_modules, which are always included. Each of these paths is used as a starting point for the module resolution algorithm, meaning that the node_modules hierarchy is checked from this location. Returns: Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename. If the module can not be found, a MODULE_NOT_FOUND error is thrown.# Added in: v8.9.0 request The module path whose lookup paths are being retrieved. Returns: <string[]> | Returns an array containing the paths searched during resolution of request or null if the request string references a core module, for example http or fs. The object# Added in: v0.1.16 In each module, the module free variable is a reference to the object representing the current module. For convenience, module.exports is also accessible via the exports module-global. module is not actually a global but rather local to each module.# Added in: v0.1.16<module[]> The module objects required for the first time by this one.# Added in: v0.1.16 The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object to module.exports. Assigning the desired object to exports will simply rebind the local exports variable, which is probably not what is desired. For example, suppose we were making a module called a.js: const EventEmitter = require('events'); module.exports = new EventEmitter(); // Do some work, and after some time emit // the 'ready' event from the module itself. setTimeout(() => { module.exports.emit('ready'); }, 1000); Then in another file we could do: const a = require('./a'); a.on('ready', () => { console.log('module "a" is ready'); }); Assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work: x.js: setTimeout(() => { module.exports = { a: 'hello' }; }, 0); y.js: const x = require('./x'); console.log(x.a); shortcut# Added in: v0.1.16 The exports variable is available within a module's file-level scope, and is assigned the value of module.exports before the module is evaluated. It allows a shortcut, so that module.exports.f = ... can be written more succinctly as exports.f = .... However, be aware that like any variable, if a new value is assigned to exports, it is no longer bound to module.exports: module.exports.hello = true; // Exported from require of module exports = { hello: false }; // Not exported, only available in the module When the module.exports property is being completely replaced by a new object, it is common to also reassign exports: module.exports = exports = function Constructor() { // ... etc. }; To illustrate the behavior, imagine this hypothetical implementation of require(), which is quite similar to what is actually done by require(): function require(/* ... */) { const module = { exports: {} }; ((module, exports) => { // Module code here. In this example, define a function. function someFunc() {} exports = someFunc; // At this point, exports is no longer a shortcut to module.exports, and // this module will still export an empty default object. module.exports = someFunc; // At this point, the module will now export someFunc, instead of the // default object. })(module, module.exports); return module.exports; } # Added in: v0.1.16 The fully resolved filename of the module.# Added in: v0.1.16 The identifier for the module. Typically this is the fully resolved filename.# Added in: v15.4.0 Type: true if the module is running during the Node.js preload phase.# Added in: v0.1.16 Whether or not the module is done loading, or is in the process of loading.# Added in: v0.1.16Deprecated since: v14.6.0, v12.19.0 Stability: 0 - Deprecated: Please use require.main and module.children instead. | | The module that first required this one, or null if the current module is the entry point of the current process, or undefined if the module was loaded by something that is not a CommonJS module (E.G.: REPL or import).# Added in: v11.14.0 The directory name of the module. This is usually the same as the path.dirname() of the module.id.# Added in: v0.4.0<string[]> The search paths for the module.# Added in: v0.5.1 id Returns: exported module content The module.require() method provides a way to load a module as if require() was called from the original module. In order to do this, it is necessary to get a reference to the module object. Since require() returns the module.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used. The object# This section was moved to Modules: module core module. module.builtinModules module.createRequire(filename)
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu where-is-npm-pack When you install a package using npm you can perform 2 types of installation: a local install a global install By default, when you type an npm install command, like: the package is installed in the current file tree, under the node_modules subfolder. As this happens, npm also adds the lodash entry in the dependencies property of the package.json file present in the current folder. A global installation is performed using the -g flag: When this happens, npm won't install the package under the local folder, but instead, it will use a global location. Where, exactly? The npm root -g command will tell you where that exact location is on your machine. On macOS or Linux this location could be /usr/local/lib/node modules. On Windows it could be C:\Users\YOU\AppData\Roaming\npm\node modules If you use nvm to manage Node.js versions, however, that location would differ. I for example use nvm and my packages location was shown as /Users/joe/.nvm/versions/node/v8.9.0/lib/node_modules. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Node APIs With Express Overview REST is a generally agreed-upon set of principles and constraints. They are recommendations, not a standard.// inside /api/apiRoutes.js <- this can be place anywhere and called anything const express = require('express'); // if the other routers are not nested inside /api then the paths would change const userRoutes = require('./users/userRoutes'); const productRoutes = require('./products/productRoutes'); const clientRoutes = require('./clients/clientRoutes'); const router = express.Router(); // notice the Uppercase R // this file will only be used when the route begins with "/api" // so we can remove that from the URLs, so "/api/users" becomes simply "/users" router.use('/users', userRoutes); router.use('/products', productRoutes); router.use('/clients', clientRoutes); // .. and any other endpoint related to the user's resource // after the route has been fully configured, we then export it so it can be required where needed module.exports = router; // standard convention dictates that this is the last line on the file ### Objective 1 — explain the role of a foreign key Overview Foreign keys are a type of table field used for creating links between tables. Like primary keys, they are most often integers that identify (rather than store) data. However, whereas a primary key is used to id rows in a table, foreign keys are used to connect a record in one table to a record in a second table. Follow Along Consider the following farms and ranchers tables. Untitled Untitled The farm_id in the ranchers table is an example of a foreign key. Each entry in the farm_id (foreign key) column corresponds to an id (primary key) in the farms table. This allows us to track which farm each rancher belongs to while keeping the tables normalized. If we could only see the ranchers table, we would know that John, Jane, and Jen all work together and that Jim and Jay also work together. However, to know where any of them work, we would need to look at the farms table. Challenge Open SQLTryIT (Links to an external site.). How many records in the products table belong to the category “confections”? Objective 2 — query data from multiple tables Now that we understand the basics of querying data from a single table, let's move on to selecting data from multiple tables using JOIN operations. Overview We can use a JOIN to combine query data from multiple tables using a single SELECT statement. There are different types of joins; some are listed below: inner joins. outer joins. left joins. right joins. cross joins. non-equality joins. self joins. Using joins requires that the two tables of interest contain at least one field with shared information. For example, if a departments table has an id field, and an employee table has a department id_ field, and the values that exist in the id column of the departments table live in the department id_ field of the employee table, we can use those fields to join both tables like so: select * from employees join departments on employees.department_id = departments.id This query will return the data from both tables for every instance where the ON condition is true. If there are employees with no value for department id or where the value stored in the field does not correspond to an existing id in the departments table, then that record will NOT be returned. In a similar fashion, any records from the departments table that don't have an employee associated with them will also be omitted from the results. Basically, if the id* does not show as the value of department_id for an employee, it won't be able to join. We can shorten the condition by giving the table names an alias. This is a common practice. Below is the same example using aliases, picking which fields to return and sorting the results: select d.id, d.name, e.id, e.first_name, e.last_name, e.salary from employees as e join departments as d on e.department_id = d.id order by d.name, e.last_name Notice that we can take advantage of white space and indentation to make queries more readable. There are several ways of writing joins, but the one shown here should work on all database management systems and avoid some pitfalls, so we recommend it. The syntax for performing a similar join using Knex is as follows: db('employees as e') .join('departments as d', 'e.department_id', 'd.id') .select('d.id', 'd.name', 'e.first_name', 'e.last_name', 'e.salary') Follow Along A good explanation of how the different types of joins can be seen in this article from w3resource.com (Links to an external site.). Challenge Use this online tool (Links to an external site.) to write the following queries: list the products, including their category name. list the products, including the supplier name. list the products, including both the category name and supplier name. What is SQL Joins? An SQL JOIN clause combines rows from two or more tables. It creates a set of rows in a temporary table. How to Join two tables in SQL? A JOIN works on two or more tables if they have at least one common field and have a relationship between them. JOIN keeps the base tables (structure and data) unchanged. Join vs. Subquery JOINs are faster than a subquery and it is very rare that the opposite. In JOINs the RDBMS calculates an execution plan, that can predict, what data should be loaded and how much it will take to processed and as a result this process save some times, unlike the subquery there is no pre-process calculation and run all the queries and load all their data to do the processing. A JOIN is checked conditions first and then put it into table and displays; where as a subquery take separate temp table internally and checking condition. When joins are using, there should be connection between two or more than two tables and each table has a relation with other while subquery means query inside another query, has no need to relation, it works on columns and conditions. SQL JOINS: EQUI JOIN and NON EQUI JOIN The are two types of SQL JOINS — EQUI JOIN and NON EQUI JOIN SQL EQUI JOIN : The SQL EQUI JOIN is a simple SQL join uses the equal sign(=) as the comparison operator for the condition. It has two types — SQL Outer join and SQL Inner join. SQL NON EQUI JOIN : The SQL NON EQUI JOIN is a join uses comparison operator other than the equal sign like >, <, >=, <= with the condition. SQL EQUI JOIN : INNER JOIN and OUTER JOIN The SQL EQUI JOIN can be classified into two types — INNER JOIN and OUTER JOIN SQL INNER JOIN This type of EQUI JOIN returns all rows from tables where the key record of one table is equal to the key records of another table. SQL OUTER JOIN This type of EQUI JOIN returns all rows from one table and only those rows from the secondary table where the joined condition is satisfying i.e. the columns are equal in both tables. In order to perform a JOIN query, the required information we need are: a) The name of the tables b) Name of the columns of two or more tables, based on which a condition will perform. Syntax: FROM table1 join_type table2 [ON (join_condition)] Parameters: Untitled Pictorial Presentation of SQL Joins:**Example:** Sample table: company Sample table: foods To join two tables 'company' and 'foods', the following SQL statement can be used : SQL Code: SELECT company.company_id,company.company_name, foods.item_id,foods.item_name FROM company,foods; Copy Output: COMPAN COMPANY_NAME ITEM_ID ITEM_NAME ------ ------------------------- -------- --------------- 18 Order All 1 Chex Mix 18 Order All 6 Cheez-It 18 Order All 2 BN Biscuit 18 Order All 3 Mighty Munch 18 Order All 4 Pot Rice 18 Order All 5 Jaffa Cakes 18 Order All 7 Salt n Shake 15 Jack Hill Ltd 1 Chex Mix 15 Jack Hill Ltd 6 Cheez-It 15 Jack Hill Ltd 2 BN Biscuit 15 Jack Hill Ltd 3 Mighty Munch 15 Jack Hill Ltd 4 Pot Rice 15 Jack Hill Ltd 5 Jaffa Cakes 15 Jack Hill Ltd 7 Salt n Shake 16 Akas Foods 1 Chex Mix 16 Akas Foods 6 Cheez-It 16 Akas Foods 2 BN Biscuit 16 Akas Foods 3 Mighty Munch 16 Akas Foods 4 Pot Rice 16 Akas Foods 5 Jaffa Cakes 16 Akas Foods 7 Salt n Shake ......... ......... ......... JOINS: Relational Databases Oracle JOINS MySQL JOINS PostgreSQL JOINS SQLite JOINS Key points to remember: Click on the following to get the slides presentation -### Practice SQL Exercises SQL Exercises, Practice, Solution SQL Retrieve data from tables [33 Exercises] SQL Boolean and Relational operators [12 Exercises] SQL Wildcard and Special operators [22 Exercises] SQL Aggregate Functions [25 Exercises] SQL Formatting query output [10 Exercises] SQL Quering on Multiple Tables [7 Exercises] FILTERING and SORTING on HR Database [38 Exercises] SQL JOINS SQL JOINS [29 Exercises] SQL JOINS on HR Database [27 Exercises] SQL SUBQUERIES SQL SUBQUERIES [39 Exercises] SQL SUBQUERIES on HR Database [55 Exercises] SQL Union[9 Exercises] SQL View[16 Exercises] SQL User Account Management [16 Exercise] Movie Database BASIC queries on movie Database [10 Exercises] SUBQUERIES on movie Database [16 Exercises] JOINS on movie Database [24 Exercises] Soccer Database Introduction BASIC queries on soccer Database [29 Exercises] SUBQUERIES on soccer Database [33 Exercises] JOINS queries on soccer Database [61 Exercises] Hospital Database Introduction BASIC, SUBQUERIES, and JOINS [39 Exercises] Employee Database BASIC queries on employee Database [115 Exercises] SUBQUERIES on employee Database [77 Exercises] More to come! Objective 3 — write database access methods Overview While we can write database code directly into our endpoints, best practices dictate that all database logic exists in separate, modular methods. These files containing database access helpers are often called models Follow Along To handle CRUD operations for a single resource, we would want to create a model (or database access file) containing the following methods: function find() { } function findById(id) { } function add(user) { } function update(changes, id) { } function remove(id) { } Each of these functions would use Knex logic to perform the necessary database operation. function find() { return db('users'); } For each method, we can choose what value to return. For example, we may prefer findById() to return a single user object rather than an array. function findById(id) { // first() returns the first entry in the db matching the query return db('users').where({ id }).first(); } We can also use existing methods like findById() to help add() return the new user (instead of just the id). function add(user) { db('users').insert(user) .then(ids => { return findById(ids[0]); }); } Once all methods are written as desired, we can export them like so: module.exports = { find, findById, add, update, delete, } …and use the helpers in our endpoints const User = require('./user-model.js'); router.get('/', (req, res) => { User.find() .then(users => { res.json(users); }) .catch(&nbsp;err => {}); }); There should no be knex code in the endpoints themselves.### A database is a collection of data organized for easy retrieval and manipulation. We're concerned only with digital databases, those that run on computers or other electronic devices. Digital databases have been around since the 1960s. Relational databases, those which store “related” data, are the oldest and most common type of database in use today. Data Persistence A database is often necessary because our application or code requires data persistence. This term refers to data that is infrequently accessed and not likely to be modified. In less technical terms, the information will be safely stored and remain untouched unless intentionally modified. A familiar example of non-persistent data would be JavaScript objects and arrays, which reset each time the code runs. Relational Databases In relational databases, the data is stored in tabular format grouped into rows and columns (similar to spreadsheets). A collection of rows is called a table. Each row represents a single record in the table and is made up of one or more columns. These kinds of databases are relational because a relation is a mathematical idea equivalent to a table. So relational databases are databases that store their data in tables. Tables Below are some basic facts about tables: Tables organize data in rows and columns. Each row in a table represents one distinct record. Each column represents a field or attribute that is common to all the records. Fields should have a descriptive name and a data type appropriate for the attribute it represents. Tables usually have more rows than columns. Tables have primary keys that uniquely identify each row. Foreign keys represent the relationships with other tables.### SQL: SQL is a standard language, which means that it almost certainly will be supported, no matter how your database is managed. That said, be aware that the SQL language can vary depending on database management tools. This lesson focuses on a set of core commands that never change. Learning the standard commands is an excellent introduction since the knowledge transfers between database products. The syntax for SQL is English-like and requires fewer symbols than programming languages like C, Java, and JavaScript. It is declarative and concise, which means there is a lot less to learn to use it effectively. When learning SQL, it is helpful to understand that each command is designed for a different purpose. If we classify the commands by purpose, we'll end up with the following sub-categories of SQL: Data Definition Language (DDL): used to modify database objects. Some examples are: CREATE TABLE, ALTER TABLE, and DROP TABLE. Data Manipulation Language (DML): used to manipulate the data stored in the database. Some examples are: INSERT, UPDATE, and DELETE. Data Query Language (DQL): used to ask questions about the data stored in the database. The most commonly used SQL command is SELECT, and it falls in this category. Data Control Language (DCL): used to manage database security and user's access to data. These commands fall into the realm of Database Administrators. Some examples are GRANT and REVOKE. Transaction Control Commands: used for managing groups of statements that must execute as a unit or not execute at all. Examples are COMMIT and ROLLBACK. As a developer, you'll need to get familiar with DDL and become proficient using DML and DQL. This lesson will cover only DML and DQL commands. The four SQL operations covered in this section will allow a user to **query**, **insert**, and **modify** a database table. Query A query is a SQL statement used to retrieve data from a database. The command used to write queries is SELECT, and it is one of the most commonly used SQL commands. The basic syntax for a SELECT statement is this: select <selection> from <table name>; To see all the fields on a table, we can use a * as the selection. select * from employees; The preceding statement would show all the records and all the columns for each record in the employees table. To pick the fields we want to see, we use a comma-separated list: select first_name, last_name, salary from employees; The return of that statement would hold all records from the listed fields. We can extend the SELECT command's capabilities using clauses for things like filtering, sorting, pagination, and more. It is possible to query multiple tables in a single query. But, in this section, we only perform queries on a single table. We will cover performing queries on multiple tables in another section. Insert To insert new data into a table, we'll use the INSERT command. The basic syntax for an INSERT statement is this: insert into <table name> (<selection>) values (<values>) Using this formula, we can specify which values will be inserted into which fields like so: insert into Customers (Country, CustomerName, ContactName, Address, City, PostalCode) values ('USA', 'WebDev School', 'Austen Allred', '1 WebDev Court', 'Provo', '84601'); Modify Modifying a database consists of updating and removing records. For these operations, we'll use UPDATE and DELETE commands, respectively. The basic syntax for an UPDATE statement is: update <table name> set <field> = <value> where <condition>; The basic syntax for a DELETE statement is: delete from <table name> where <condition>; ### Filtering results using WHERE clause When querying a database, the default result will be every entry in the given table. However, often, we are looking for a specific record or a set of records that meets certain criteria. A WHERE clause can help in both cases. Here's an example where we might only want to find customers living in Berlin. select City, CustomerName, ContactName from Customers where City = 'Berlin' We can also chain together WHERE clauses using OR and AND to limit our results further. The following query includes only records that match both criteria. select City, CustomerName, ContactName from Customers where Country = 'France' and City = 'Paris' And this query includes records that match either criteria. select City, CustomerName, ContactName from Customers where Country = 'France' or City = 'Paris' These operators can be combined and grouped with parentheses to add complex selection logic. They behave similarly to what you're used to in programming languages. You can read more about SQLite operators from w3resource (Links to an external site.). To select a single record, we can use a WHERE statement with a uniquely identifying field, like an id: select * from Customers where CustomerId=3; Other comparison operators also work in WHERE conditions, such as >, <, <=, and >=. select * from employees where salary >= 50000 Ordering results using the ORDER BY clause Query results are shown in the same order the data was inserted. To control how the data is sorted, we can use the ORDER BY clause. Let's see an example.-- sorts the results first by salary in descending order, then by the last name in ascending order select * from employees order by salary desc, last_name; We can pass a list of field names to order by and optionally choose asc or desc for the sort direction. The default is asc, so it doesn't need to be specified. Some SQL engines also support using field abbreviations when sorting. select name, salary, department from employees order by 3, 2 desc; In this case, the results are sorted by the department in ascending order first and then by salary in descending order. The numbers refer to the fields' position in the selection portion of the query, so 1 would be name, 2 would be salary, and so on. Note that the WHERE clause should come after the FROM clause. The ORDER BY clause always goes last. select * from employees where salary > 50000 order by last_name; Limiting results using the LIMIT clause When we wish to see only a limited number of records, we can use a LIMIT clause. The following returns the first ten records in the products table: select * from products limit 10 LIMIT clauses are often used in conjunction with ORDER BY. The following shows us the five cheapest products: select * from products order by price desc limit 5 Inserting data using INSERT An insert statement adds a new record to the database. All non-null fields must be listed out in the same order as their values. Some fields, like ids and timestamps, may be auto-generated and do not need to be included in an INSERT statement.-- we can add fields in any order; the values need to be in the same ordinal position -- the id will be assigned automatically insert into Customers (Country, CustomerName, ContactName, Address, City, PostalCode) values ('USA', 'WebDev School', 'Austen Allred', '1 WebDev Court', 'Provo', '84601'); The values in an insert statement must not violate any restrictions and constraints that the database has in place, such as expected datatypes. We will learn more about constraints and schema design in a later section. Modifying recording using UPDATE When modifying a record, we identify a single record or a set of records to update using a WHERE clause. Then we can set the new value(s) in place. update Customers set City = 'Silicon Valley', Country = 'USA' where CustomerName = 'WebDev School' Technically the WHERE clause is not required, but leaving it off would result in every record within the table receiving the update. Removing records using DELETE When removing a record or set of records, we need only identify which record(s) to remove using a WHERE clause: delete from Customers where CustomerName = 'WebDev School`; Once again, the WHERE clause is not required, but leaving it off would remove every record in the table, so it's essential. Raw SQL is a critical baseline skill. However, Node developers generally use an **Object Relational Mapper (ORM)** or **query builder** to write database commands in a backend codebase. Both **ORMs** and **query builders** are JavaScript libraries that allow us to interface with the database using a JavaScript version of the SQL language. For example, instead of a raw SQL SELECT: SELECT * FROM users; We could use a query builder to write the same logic in JavaScript: db.select('*').from('users'); Query builders are lightweight and easy to get off the ground, whereas ORMs use an object-oriented model and provide more heavy lifting within their rigid structure. We will use a query builder called knex.js (Links to an external site.).### Knex Setup To use Knex in a repository, we'll need to add two libraries: npm install knex sqlite3 knex is our query builder library, and sqlite3 allows us to interface with a sqlite database. We'll learn more about sqlite and other database management systems in the following module. For now, know that you need both libraries. Next, we use Knex to set up a config file: const knex = require('knex'); const config = { client: 'sqlite3', connection: { filename: './data/posts.db3', }, useNullAsDefault: true, }; module.exports = knex(config); To use the query builder elsewhere in our code, we need to call knex and pass in a config object. We'll be discussing Knex configuration more in a future module. Still, we only need the client, connection, and useNullAsDefault keys as shown above. The filename should point towards the pre-existing database file, which can be recognized by the .db3 extension. GOTCHA: The file path to the database should be with respect to the root of the repo, not the configuration file itself. Once Knex is configured, we can import the above config file anywhere in our codebase to access the database. const db = require('../data/db-config.js); The db object provides methods that allow us to begin building queries. SELECT using Knex In Knex, the equivalent of SELECT * FROM users is: db.select('*').from('users'); There's a simpler way to write the same command: db('users'); Using this, we could write a GET endpoint. router.get('/api/users', (req, res) => { db('users') .then(users => { res.json(users); }) .catch (err => { res.status(500).json({ message: 'Failed to get users' }); }); }); NOTE: All Knex queries return promises. Knex also allows for a where clause. In Knex, we could write SELECT * FROM users WHERE id=1 as db('users').where({ id: 1 }); This method will resolve to an array containing a single entry like so: [{ id: 1, name: 'bill' }]. Using this, we might add a GET endpoint where a specific user: server.get('api/users/:id', (req, res) => { const { id } = req.params; db('users').where({ id }) .then(users => { // we must check the length to find our if our user exists if (users.length) { res.json(users); } else { res.status(404).json({ message: 'Could not find user with given id.' }) }) .catch (err => { res.status(500).json({ message: 'Failed to get user' }); }); }); INSERT using Knex In Knex, the equivalent of INSERT INTO users (name, age) VALUES ('Eva', 32) is: db('users').insert({ name: 'Eva', age: 32 }); The insert method in Knex will resolve to an array containing the newly created id for that user like so: [3]. UPDATE using Knex In knex, the equivalent of UPDATE users SET name='Ava', age=33 WHERE id=3; is: db('users').where({ id: 3 }) .update({name: 'Ava', age: 33 }); Note that the where method comes before update, unlike in SQL. Update will resolve to a count of rows updated. DELETE using Knex In Knex, the equivalent of DELETE FROM users WHERE age=33; is: db('users').where({ age: 33}).del(); Once again, the where must come before the del. This method will resolve to a count of records removed.### Here's a small project you can practice with. SQLlite Studio is an application that allows us to create, open, view, and modify SQLite databases. To fully understand what SQLite Studio is and how it works, we must also understand the concept of the Database Management Systems (DBMS). What is a DBMS? To manage digital databases we use specialized software called D ata B ase M anagement S ystems (DBMS). These systems typically run on servers and are managed by D ata B ase A dministrators (DBAs). In less technical terms, we need a type of software that will allow us to create, access, and generally manage our databases. In the world of relational databases, we specifically use Relational Database Mangement Systems (RDBMs). Some examples are Postgres, SQLite, MySQL, and Oracle. Choosing a DBMS determines everything from how you set up your database, to where and how the data is stored, to what SQL commands you can use. Most systems share the core of the SQL language that you've already learned. In other words, you can expect SELECT, UPDATE, INSERT, WHERE , and the like to be the same across all DBMSs, but the subtleties of the language may vary. What is SQLite? SQLite is the DBMS, as the name suggests, it is a more lightweight system and thus easier to get set up than some others. SQLite allows us to store databases as single files. SQLite projects have a .db3 extension. That is the database. SQLite is not a database (like relational, graph, or document are databases) but rather a database management system. Opening an existing database in SQLite Studio One useful visual interface we might use with a SQLite database is called SQLite Studio. Install SQLITE Studio here. (Links to an external site.) Once installed, we can use SQLite Studio to open any .db3 file from a previous lesson. We may view the tables, view the data, and even make changes to the database. For a more detailed look at SQLite Studio, follow along in the video above. A **database schema** is the shape of our database. It defines what tables we'll have, which columns should exist within the tables and any restrictions on each column. A well-designed database schema keeps the data well organized and can help ensure high-quality data. Note that while schema design is usually left to Database Administrators (DBAs), understanding schema helps when designing APIs and database logic. And in a smaller team, this step may fall on the developer. For a look at schema design in SQLite Studio, follow along in the video above. When designing a single table, we need to ask three things: What fields (or columns) are present? What type of data do we expect for each field? Are there other restrictions needed for each column? Looking at the following schema diagram for an accounts table, we can the answer to each other those questions: Untitled Table Fields Choosing which fields to include in a table is relatively straight forward. What information needs to be tracked regarding this resource? In the real world, this is determined by the intended use of the product or app. However, this is one requirement every table should satisfy: a primary key. A primary key is a way to identify each entry in the database uniquely. It is most often represented as a auto-incrementing integer called id or [tablename]Id. Datatypes Each field must also have a specified datatype. The datatype available depends on our DBMS. Some supported datatype in SQLite include: Null: Missing or unknown information. Integer: Whole numbers. Real: Any number, including decimals. Text: Character data. Blob: a large binary object that can be used to store miscellaneous data. Any data inserted into the table must match the datatypes determined in schema design. Constraints Beyond datatypes, we may add additional constraints on each field. Some examples include: Not Null: The field cannot be left empty Unique: No two records can have the same value in this field Primary key: — Indicates this field is the primary key. Both the not null and unique constraints will be enforced. Default: — Sets a default value if none is provided. As with data types, any data that does not satisfy the schema constraints will be rejected from the database.### Multi-Table Design Another critical component of schema design is to understand how different tables relate to each other. This will be covered in later lesson. Knex provides a schema builder, which allows us to write code to design our database schema. However, beyond thinking about columns and constraints, we must also consider updates. When a schema needs to be updated, a developer must feel confident that the changes go into effect everywhere. This means schema updates on the developer's local machine, on any testing or staging versions, on the production database, and then on any other developer's local machines. This is where migrations come into play. A database migration describes changes made to the structure of a database. Migrations include things like adding new objects, adding new tables, and modifying existing objects or tables.### Knex Cli To use migrations (and to make Knex setup easier), we need to use knex cli. Install knex globally with npm install -g knex. This allows you to use Knex commands within any repo that has knex as a local dependency. If you have any issues with this global install, you can use the npx knex command instead. Initializing Knex To start, add the knex and sqlite3 libraries to your repository. npm install knex sqlite3 We've seen how to use manually create a config object to get started with Knex, but the best practice is to use the following command: knex init Or, if Knex isn't globally installed: npx knex init This command will generate a file in your root folder called knexfile.js. It will be auto populated with three config objects, based on different environments. We can delete all except for the development object. module.exports = { development: { client: 'sqlite3', connection: { filename: './dev.sqlite3' } } }; We'll need to update the location (or desired location) of the database as well as add the useNullAsDefault option. The latter option prevents crashes when working with sqlite3. module.exports = { development: { // our DBMS driver client: 'sqlite3', // the location of our db connection: { filename: './data/database_file.db3', }, // necessary when using sqlite3 useNullAsDefault: true } }; Now, wherever we configure our database, we may use the following syntax instead of hardcoding in a config object. const knex = require('knex'); const config = require('../knexfile.js'); // we must select the development object from our knexfile const db = knex(config.development); // export for use in codebase module.exports = db; Knex Migrations Once our knexfile is set up, we can begin creating migrations. Though it's not required, we are going to add an addition option to the config object to specify a directory for the migration files. development: { client: 'sqlite3', connection: { filename: './data/produce.db3', }, useNullAsDefault: true, // generates migration files in a data/migrations/ folder migrations: { directory: './data/migrations' } } We can generate a new migration with the following command: knex migrate:make [migration-name] If we needed to create an accounts table, we might run: knex migrate:make create-accounts Note that inside data/migrations/ a new file has appeared. Migrations have a timestamp in their filenames automatically. Wither you like this or not, do not edit migration names. The migration file should have both an up and a down function. Within the up function, we write the ended database changes. Within the down function, we write the code to undo the up functions. This allows us to undo any changes made to the schema if necessary. exports.up = function(knex, Promise) { // don't forget the return statement return knex.schema.createTable('accounts', tbl => { // creates a primary key called id tbl.increments(); // creates a text field called name which is both required and unique tbl.text('name', 128).unique().notNullable(); // creates a numeric field called budget which is required tbl.decimal('budget').notNullable(); }); }; exports.down = function(knex, Promise) { // drops the entire table return knex.schema.dropTableIfExists('accounts'); }; References for these methods are found in the schema builder section of the Knex docs (Links to an external site.). At this point, the table is not yet created. To run this (and any other) migrations, use the command: knex migrate:latest Note if the database does not exist, this command will auto-generate one. We can use SQLite Studio to confirm that the accounts table has been created. Changes and Rollbacks If later down the road, we realize you need to update your schema, you shouldn't edit the migration file. Instead, you will want to create a new migration with the command: knex migrate:make accounts-schema-update Once we've written our updates into this file we save and close with: knex migrate:latest If we migrate our database and then quickly realize something isn't right, we can edit the migration file. However, first, we need to rolllback (or undo) our last migration with: knex migrate:rollback Finally, we are free to rerun that file with knex migrate latest. NOTE: A rollback should not be used to edit an old migration file once that file has accepted into a main branch. However, an entire team may use a rollback to return to a previous version of a database. Overview Knex provides a schema builder, which allows us to write code to design our database schema. However, beyond thinking about columns and constraints, we must also consider updates. When a schema needs to be updated, a developer must feel confident that the changes go into effect everywhere. This means schema updates on the developer's local machine, on any testing or staging versions, on the production database, and then on any other developer's local machines. This is where migrations come into play. A database migration describes changes made to the structure of a database. Migrations include things like adding new objects, adding new tables, and modifying existing objects or tables.### Knex Cli To use migrations (and to make Knex setup easier), we need to use knex cli. Install knex globally with npm install -g knex. This allows you to use Knex commands within any repo that has knex as a local dependency. If you have any issues with this global install, you can use the npx knex command instead. Initializing Knex To start, add the knex and sqlite3 libraries to your repository. npm install knex sqlite3 We've seen how to use manually create a config object to get started with Knex, but the best practice is to use the following command: knex init Or, if Knex isn't globally installed: npx knex init This command will generate a file in your root folder called knexfile.js. It will be auto populated with three config objects, based on different environments. We can delete all except for the development object. module.exports = { development: { client: 'sqlite3', connection: { filename: './dev.sqlite3' } } }; We'll need to update the location (or desired location) of the database as well as add the useNullAsDefault option. The latter option prevents crashes when working with sqlite3. module.exports = { development: { // our DBMS driver client: 'sqlite3', // the location of our db connection: { filename: './data/database_file.db3', }, // necessary when using sqlite3 useNullAsDefault: true } }; Now, wherever we configure our database, we may use the following syntax instead of hardcoding in a config object. const knex = require('knex'); const config = require('../knexfile.js'); // we must select the development object from our knexfile const db = knex(config.development); // export for use in codebase module.exports = db; Knex Migrations Once our knexfile is set up, we can begin creating migrations. Though it's not required, we are going to add an addition option to the config object to specify a directory for the migration files. development: { client: 'sqlite3', connection: { filename: './data/produce.db3', }, useNullAsDefault: true, // generates migration files in a data/migrations/ folder migrations: { directory: './data/migrations' } } We can generate a new migration with the following command: knex migrate:make [migration-name] If we needed to create an accounts table, we might run: knex migrate:make create-accounts Note that inside data/migrations/ a new file has appeared. Migrations have a timestamp in their filenames automatically. Wither you like this or not, do not edit migration names. The migration file should have both an up and a down function. Within the up function, we write the ended database changes. Within the down function, we write the code to undo the up functions. This allows us to undo any changes made to the schema if necessary. exports.up = function(knex, Promise) { // don't forget the return statement return knex.schema.createTable('accounts', tbl => { // creates a primary key called id tbl.increments(); // creates a text field called name which is both required and unique tbl.text('name', 128).unique().notNullable(); // creates a numeric field called budget which is required tbl.decimal('budget').notNullable(); }); }; exports.down = function(knex, Promise) { // drops the entire table return knex.schema.dropTableIfExists('accounts'); }; References for these methods are found in the schema builder section of the Knex docs (Links to an external site.). At this point, the table is not yet created. To run this (and any other) migrations, use the command: knex migrate:latest Note if the database does not exist, this command will auto-generate one. We can use SQLite Studio to confirm that the accounts table has been created. Changes and Rollbacks If later down the road, we realize you need to update your schema, you shouldn't edit the migration file. Instead, you will want to create a new migration with the command: knex migrate:make accounts-schema-update Once we've written our updates into this file we save and close with: knex migrate:latest If we migrate our database and then quickly realize something isn't right, we can edit the migration file. However, first, we need to rolllback (or undo) our last migration with: knex migrate:rollback Finally, we are free to rerun that file with knex migrate latest. NOTE: A rollback should not be used to edit an old migration file once that file has accepted into a main branch. However, an entire team may use a rollback to return to a previous version of a database. Overview Often we want to pre-populate our database with sample data for testing. Seeds allow us to add and reset sample data easily. Follow Along The Knex command-line tool offers a way to seed our database; in other words, pre-populate our tables. Similarly to migrations, we want to customize where our seed files are generated using our knexfile development: { client: 'sqlite3', connection: { filename: './data/produce.db3', }, useNullAsDefault: true, // generates migration files in a data/migrations/ folder migrations: { directory: './data/migrations' }, seeds: { directory: './data/seeds' } } To create a seed run: knex seed:make 001-seedName Numbering is a good idea because Knex doesn't attach a timestamp to the name like migrate does. Adding numbers to the file name, we can control the order in which they run. We want to create seeds for our accounts table: knex seed:make 001-accounts A file will appear in the designated seed folder. exports.seed = function(knex, Promise) { // we want to remove all data before seeding // truncate will reset the primary key each time return knex('accounts').truncate() .then(function () { // add data into insert return knex('accounts').insert([ { name: 'Stephenson', budget: 10000 }, { name: 'Gordon & Gale', budget: 40400 }, ]); }); }; Run the seed files by typing: knex seed:run You can now use SQLite Studio to confirm that the accounts table has two entries.### SQL & PostgreSQL Foreign keys are a type of table field used for creating links between tables. Like primary keys, they are most often integers that identify (rather than store) data. However, whereas a primary key is used to id rows in a table, foreign keys are used to connect a record in one table to a record in a second table. Consider the following farms and ranchers tables. Untitled Untitled The farm_id in the ranchers table is an example of a foreign key. Each entry in the farm_id (foreign key) column corresponds to an id (primary key) in the farms table. This allows us to track which farm each rancher belongs to while keeping the tables normalized. If we could only see the ranchers table, we would know that John, Jane, and Jen all work together and that Jim and Jay also work together. However, to know where any of them work, we would need to look at the farms table. Now that we understand the basics of querying data from a single table, let's move on to selecting data from multiple tables using JOIN operations. Overview We can use a JOIN to combine query data from multiple tables using a single SELECT statement. There are different types of joins; some are listed below: inner joins. outer joins. left joins. right joins. cross joins. non-equality joins. self joins. Using joins requires that the two tables of interest contain at least one field with shared information. For example, if a departments table has an id field, and an employee table has a department id_ field, and the values that exist in the id column of the departments table live in the department id_ field of the employee table, we can use those fields to join both tables like so: select * from employees join departments on employees.department_id = departments.id This query will return the data from both tables for every instance where the ON condition is true. If there are employees with no value for department id or where the value stored in the field does not correspond to an existing id in the departments table, then that record will NOT be returned. In a similar fashion, any records from the departments table that don't have an employee associated with them will also be omitted from the results. Basically, if the id* does not show as the value of department_id for an employee, it won't be able to join. We can shorten the condition by giving the table names an alias. This is a common practice. Below is the same example using aliases, picking which fields to return and sorting the results: select d.id, d.name, e.id, e.first_name, e.last_name, e.salary from employees as e join departments as d on e.department_id = d.id order by d.name, e.last_name Notice that we can take advantage of white space and indentation to make queries more readable. There are several ways of writing joins, but the one shown here should work on all database management systems and avoid some pitfalls, so we recommend it. The syntax for performing a similar join using Knex is as follows: db('employees as e') .join('departments as d', 'e.department_id', 'd.id') .select('d.id', 'd.name', 'e.first_name', 'e.last_name', 'e.salary') Follow Along A good explanation of how the different types of joins can be seen in this article from w3resource.com (Links to an external site.). What is SQL Joins? An SQL JOIN clause combines rows from two or more tables. It creates a set of rows in a temporary table. How to Join two tables in SQL? A JOIN works on two or more tables if they have at least one common field and have a relationship between them. JOIN keeps the base tables (structure and data) unchanged. Join vs. Subquery JOINs are faster than a subquery and it is very rare that the opposite. In JOINs the RDBMS calculates an execution plan, that can predict, what data should be loaded and how much it will take to processed and as a result this process save some times, unlike the subquery there is no pre-process calculation and run all the queries and load all their data to do the processing. A JOIN is checked conditions first and then put it into table and displays; where as a subquery take separate temp table internally and checking condition. When joins are using, there should be connection between two or more than two tables and each table has a relation with other while subquery means query inside another query, has no need to relation, it works on columns and conditions. SQL JOINS: EQUI JOIN and NON EQUI JOIN The are two types of SQL JOINS — EQUI JOIN and NON EQUI JOIN SQL EQUI JOIN : The SQL EQUI JOIN is a simple SQL join uses the equal sign(=) as the comparison operator for the condition. It has two types — SQL Outer join and SQL Inner join. SQL NON EQUI JOIN : The SQL NON EQUI JOIN is a join uses comparison operator other than the equal sign like >, <, >=, <= with the condition. SQL EQUI JOIN : INNER JOIN and OUTER JOIN The SQL EQUI JOIN can be classified into two types — INNER JOIN and OUTER JOIN SQL INNER JOIN This type of EQUI JOIN returns all rows from tables where the key record of one table is equal to the key records of another table. SQL OUTER JOIN This type of EQUI JOIN returns all rows from one table and only those rows from the secondary table where the joined condition is satisfying i.e. the columns are equal in both tables. In order to perform a JOIN query, the required information we need are: a) The name of the tables b) Name of the columns of two or more tables, based on which a condition will perform. Syntax: FROM table1 join_type table2 [ON (join_condition)] Parameters: Untitled Pictorial Presentation of SQL Joins:**Example:** Sample table: company Sample table: foods To join two tables 'company' and 'foods', the following SQL statement can be used : SQL Code: SELECT company.company_id,company.company_name, foods.item_id,foods.item_name FROM company,foods; Copy Output: COMPAN COMPANY_NAME ITEM_ID ITEM_NAME ------ ------------------------- -------- --------------- 18 Order All 1 Chex Mix 18 Order All 6 Cheez-It 18 Order All 2 BN Biscuit 18 Order All 3 Mighty Munch 18 Order All 4 Pot Rice 18 Order All 5 Jaffa Cakes 18 Order All 7 Salt n Shake 15 Jack Hill Ltd 1 Chex Mix 15 Jack Hill Ltd 6 Cheez-It 15 Jack Hill Ltd 2 BN Biscuit 15 Jack Hill Ltd 3 Mighty Munch 15 Jack Hill Ltd 4 Pot Rice 15 Jack Hill Ltd 5 Jaffa Cakes 15 Jack Hill Ltd 7 Salt n Shake 16 Akas Foods 1 Chex Mix 16 Akas Foods 6 Cheez-It 16 Akas Foods 2 BN Biscuit 16 Akas Foods 3 Mighty Munch 16 Akas Foods 4 Pot Rice 16 Akas Foods 5 Jaffa Cakes 16 Akas Foods 7 Salt n Shake ......... ......... ......... Overview While we can write database code directly into our endpoints, best practices dictate that all database logic exists in separate, modular methods. These files containing database access helpers are often called models Follow Along To handle CRUD operations for a single resource, we would want to create a model (or database access file) containing the following methods: function find() { } function findById(id) { } function add(user) { } function update(changes, id) { } function remove(id) { } Each of these functions would use Knex logic to perform the necessary database operation. function find() { return db('users'); } For each method, we can choose what value to return. For example, we may prefer findById() to return a single user object rather than an array. function findById(id) { // first() returns the first entry in the db matching the query return db('users').where({ id }).first(); } We can also use existing methods like findById() to help add() return the new user (instead of just the id). function add(user) { db('users').insert(user) .then(ids => { return findById(ids[0]); }); } Once all methods are written as desired, we can export them like so: module.exports = { find, findById, add, update, delete, } …and use the helpers in our endpoints const User = require('./user-model.js'); router.get('/', (req, res) => { User.find() .then(users => { res.json(users); }) .catch(&nbsp;err => {}); }); There should no be knex code in the endpoints themselves.### Normalization is the process of designing or refactoring database tables for maximum consistency and minimum redundancy. With objects, we're used to denormalized data, stored with ease of use and speed in mind. Non-normalized tables are considered ineffective in relational databases. Data normalization is a deep topic in database design. To begin thinking about it, we'll explore a few basic guidelines and some data examples that violate these rules. Normalization Guidelines Each record has a primary key. No fields are repeated. All fields relate directly to the key data. Each field entry contains a single data point. There are no redundant entries. Denormalized Data Untitled This table has two issues. There is no proper id field (as multiple farms may have the same name), and multiple fields are representing the same type of data: animals. Untitled While we have now eliminated the first two issues, we now have multiple entries in one field, separated by commas. This isn't good either, as its another example of denormalization. There is no “array” data type in a relational database, so each field must contain only one data point. Untitled Now we've solved the multiple fields issue, but we created repeating data (the farm field), which is also an example of denormalization. As well, we can see that if we were tracking additional ranch information (such as annual revenue), that field is only vaguely related to the animal information. When these issues begin arising in your schema design, it means that you should separate information into two or more tables. Anomalies Obeying the above guidelines prevent anomalies in your database when inserting, updating, or deleting. For example, imagine if the revenue of Beech Ranch changed. With our denormalized schema, it may get updated in some records but not others: Untitled Similarly, if Beech Ranch shut down, there would be three (if not more) records that needed to be deleted to remove a single farm. Thus a denormalized table opens the door for contradictory, confusing, and unusable data. What issues does the following table have? Untitled There are three types of relationships: One to one. One to many. Many to many. Determining how data is related can provide a set of guidelines for table representation and guides the use of foreign keys to connect said tables. One to One Relationships Imagine we are storing the financial projections for a series of farms. We may wish to attach fields like farm name, address, description, projected revenue, and projected expenses. We could divide these fields into two categories: information related to the farm directly (name, address, description) and information related to the financial projections (revenue, expenses). We would say that farms and projections have a one-to-one relationship. This is to say that every farm has exactly one projection, and every project corresponds to exactly one farm. This data can be represented in two tables: farms and projections Untitled Untitled The farm_id is the foreign key that links farms and projections together. Notes about one-to-one relationships: The foreign key should always have a unique constraint to prevent duplicate entries. In the example above, we wouldn't want to allow multiple projections records for one farm. The foreign key can be in either table. For example, we may have had a projection_id in the farms table instead. A good rule of thumb is to put the foreign key in whichever table is more auxiliary to the other. You can represent one-to-one data in a single table without creating anomalies. However, it is sometimes prudent to use two tables as shown above to keep separate concerns in separate tables. One to Many Relationships Now imagine, we are storing the full-time ranchers employed at each farm. In this case, each rancher would only work at one farm however, each farm may have multiple ranchers. This is called a one-to-many relationship. This is the most common type of relationship between entities. Some other examples: One customer can have many orders. One user can have many posts. One post can have many comments. Manage this type of relationship by adding a foreign key on the “many” table of the relationship that points to the primary key on the “one” table. Consider the farms and ranchers tables. Untitled Untitled In a many-to-many relationship, the foreign key (in this case farm_id) should not be unique. Many to Many Relationships If we want to track animals on a farm as well, we must explore the many-to-many relationship. A farm has multiple animals, and multiple of each type of animal is present at multiple different farms. Some other examples: an order can have many products and the same product will appear in many orders. a book can have more than one author, and an author can write more than one book. To model this relationship, we need to introduce an intermediary table that holds foreign keys that reference the primary key on the related tables. We now have a farms, animals, and farm_animals table. Untitled Untitled Untitled While each foreign key on the intermediary table is not unique, the combinations of keys should be unique. The Knex query builder library also allows us to create multi-table schemas include foreign keys. However, there are a few extra things to keep in mind when designing a multi-table schema, such as using the correct order when creating tables, dropping tables, seeding data, and removing data. We have to consider the way that delete and updates through our API will impact related data. Foreign Key Setup In Knex, foreign key restrictions don't automatically work. Whenever using foreign keys in your schema, add the following code to your knexfile. This will prevent users from entering bad data into a foreign key column. development: { client: 'sqlite3', useNullAsDefault: true, connection: { filename: './data/database.db3', }, // needed when using foreign keys pool: { afterCreate: (conn, done) => { // runs after a connection is made to the sqlite engine conn.run('PRAGMA foreign_keys = ON', done); // turn on FK enforcement }, }, }, Migrations Let's look at how we might track our farms and ranchers using Knex. In our migration file's up function, we would want to create two tables: exports.up = function(knex, Promise) { return knex.schema .createTable('farms', tbl => { tbl.increments(); tbl.string('farm_name', 128) .notNullable(); }) // we can chain together createTable .createTable('ranchers', tbl => { tbl.increments(); tbl.string('rancher_name', 128); tbl.integer('farm_id') // forces integer to be positive .unsigned() .notNullable() .references('id') // this table must exist already .inTable('farms') }) }; Note that the foreign key can only be created after the reference table. In the down function, the opposite is true. We always want to drop a table with a foreign key before dropping the table it references. exports.down = function(knex, Promise) { // drop in the opposite order return knex.schema .dropTableIfExists('ranchers') .dropTableIfExists('farms') }; In the case of a many-to-many relationship, the syntax for creating an intermediary table is identical, except for one additional piece. We need a way to make sure our combination of foreign keys is unique..createTable('farm_animals', tbl => { tbl.integer('farm_id') .unsigned() .notNullable() .references('id') // this table must exist already .inTable('farms') tbl.integer('animal_id') .unsigned() .notNullable() .references('id') // this table must exist already .inTable('animals') // the combination of the two keys becomes our primary key // will enforce unique combinations of ids tbl.primary(['farm_id', 'animal_id']); }); Seeds Order is also a concern when seeding. We want to create seeds in the same order we created our tables. In other words, don't create a seed with a foreign key, until that reference record exists. In our example, make sure to write the 01-farms seed file and then the 02-ranchers seed file. However, we run into a problem with truncating our seeds, because we want to truncate 02-ranchers before 01-farms. A library called knex-cleaner provides an easy solution for us. Run knex seed:make 00-cleanup and npm install knex-cleaner. Inside the cleanup seed, use the following code. const cleaner = require('knex-cleaner'); exports.seed = function(knex) { return cleaner.clean(knex, { mode: 'truncate', // resets ids ignoreTables: ['knex_migrations', 'knex_migrations_lock'], // don't empty migration tables }); }; This removes all tables (excluding the two tables that track migrations) in the correct order before any seed files run. Cascading If a user attempt to delete a record that is referenced by another record (such as attempting to delete Morton Ranch when entries in our ranchers table reference that record), by default, the database will block the action. The same thing can happen when updating a record when a foreign key reference. If we want that to override this default, we can delete or update with cascade. With cascade, deleting a record also deletes all referencing records, we can set that up in our schema..createTable('ranchers', tbl => { tbl.increments(); tbl.string('rancher_name', 128); tbl.integer('farm_id') .unsigned() .notNullable() .references('id') .inTable('farms') .onUpdate('CASCADE'); .onDelete('CASCADE') })
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    lorem-ipsum Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Node Modules System how we introduce modularity into our code in the node ecosystem Node.js has a built-in module system. A Node.js file can import functionality exposed by other Node.js files. When you want to import something you use to import the functionality exposed in the library.js file that resides in the current file folder. In this file, functionality must be exposed before it can be imported by other files. Any other object or variable defined in the file by default is private and not exposed to the outer world. This is what the module.exports API offered by the module system allows us to do. When you assign an object or a function as a new exports property, that is the thing that's being exposed, and as such, it can be imported in other parts of your app, or in other apps as well. You can do so in 2 ways. The first is to assign an object to module.exports, which is an object provided out of the box by the module system, and this will make your file export just that object: The second way is to add the exported object as a property of exports. This way allows you to export multiple objects, functions or data: or directly And in the other file, you'll use it by referencing a property of your import: or What's the difference between module.exports and exports? The first exposes the object it points to. The latter exposes the properties of the object it points to. Modules in Javascript Differences between Node.js and browsers Modules in Javascript Differences between Node.js and browsers There are many differences between Node.js and browser environments, but many of them are small and inconsequential in practice. For example, in our Asynchronous lesson, we noted how Node’s setTimeout has a slightly different return value from a browser’s setTimeout. Let’s go over a few notable differences between the two environments. Global vs Window In the Node.js runtime, the global object is the object where global variables are stored. In browsers, the window object is where global variables are stored. The window also includes properties and methods that deal with drawing things on the screen like images, links, and buttons. Node doesn’t need to draw anything, and so it does not come with such properties. This means that you can’t reference window in Node. Most browsers allow you to reference global but it is really the same object as window. Document Browsers have access to a document object that contains the HTML of a page that will be rendered to the browser window. There is no document in Node. Location Browsers have access to a location that contains information about the web address being visited in the browser. There is no location in Node, since it is not on the web. Require and module.exports Node has a predefined require function that we can use to import installed modules like readline. We can also import and export across our own files using require and module.exports. For example, say we had two different files, animals.js and cat.js, that existed in the same directory: If we execute animals.js in Node, the program would print ‘Sennacy is a great pet!’. Browsers don’t have a notion of a file system so we cannot use require or module.exports in the same way. The fs module Node comes with an fs module that contains methods that allow us to interact with our computer’s F ile S ystem through JavaScript. No additional installations are required; to access this module we can simply require it. We recommend that you code along with this reading. Let's begin with a change-some-files.js script that imports the module:// change-some-files.js const fs = require("fs"); Similar to what we saw in the readline lesson, require will return to us a object with many properties that will enable us to do file I/O. Did you know? I/O is short for input/output. It’s usage is widespread and all the hip tech companies are using it, like.io. The fs module contains tons of functionality! Chances are that if there is some operation you need to perform regarding files, the fs module supports it. The module also offers both synchronous and asynchronous implementations of these methods. We prefer to not block the thread and so we'll opt for the asynchronous flavors of these methods. Creating a new file To create a file, we can use the writeFile method. According to the documentation, there are a few ways to use it. The most straight forward way is: The code a create-a-nnew-file.js (github.com) bove will create a new file called foo.txt in the same directory as our change-some-file.js script. It will write the string 'Hello world!' into that newly created file. The third argument specifies the encoding of the characters. There are different ways to encode characters; UTF-8 is the most common and you'll use this in most scenarios. The fourth argument to writeFile is a callback that will be invoked when the write operation is complete. The docs indicate that if there is an error during the operation (such as an invalid encoding argument), an error object will be passed into the callback. This type of error handling is quite common for asynchronous functions. Like we are used to, since writeFile is asynchronous, we need to utilize callback chaining if we want to guarantee that commands occur after the write is complete or fails. Beware! If the file name specified to writeFile already exists, it will completely overwrite the contents of that file. We won’t be using the foo.txt file in the rest of this reading. Reading existing files To explore how to read a file, we’ll use VSCode to manually create a poetry.txt file within the same directory as our change-some-file.js script. Be sure to create this if you are following along. Our poetry.txt file will contain the following lines: My code fails I do not know why My code works I do not know why We can use the readFile method to read the contents of this file. The method accepts very similar arguments to writeFile, except that the callback may be passed an error object and string containing the file contents. In the snippet below, we have replaced our previous writeFile code with readFile: Running the code above would print the following in the terminal: THE CONTENTS ARE: My code fails I do not know why My code works I do not know why Success! From here, you can do anything you please with the data read from the file. For example, since data is a string, we could split the string on the newline character \n to obtain an array of the file's lines: THE CONTENTS ARE: [ 'My code fails', 'I do not know why', 'My code works', 'I do not know why' ] The third line is My code works File I/O Using the same poetry.txt file from before: My code fails I do not know why My code works I do not know why Let’s replace occurrences of the phrase ‘do not’ with the word ‘should’. We can read the contents of the file as a string, manipulate this string, then write this new string back into the file. We’ll need to utilize callback chaining in order for this to work since our file I/O is asynchronous: Executing the script above will edit the poetry.txt file to contain: My code fails I should know why My code works I should know why Refactor: If you found this guide helpful feel free to checkout my github/gists where I host similar content: bgoonz’s gists · GitHub bgoonz — Overview Web Developer, Electrical Engineer JavaScript | CSS | Bootstrap | Python | React | Node.js | Express | Sequelize… github.com
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    insert-into-array Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Intro To Node
    Intro To Node Node.js is an open-source and cross-platform JavaScript runtime environment. It is a popular tool for almost any kind of project! Node.js runs the V8 JavaScript engine, the core of Google Chrome, outside of the browser. This allows Node.js to be very performant. A Node.js app is run in a single process, without creating a new thread for every request. Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm. When Node.js performs an I/O operation, like reading from the network, accessing a database or the filesystem, instead of blocking the thread and wasting CPU cycles waiting, Node.js will resume the operations when the response comes back. This allows Node.js to handle thousands of concurrent connections with a single server without introducing the burden of managing thread concurrency, which could be a significant source of bugs. Node.js has a unique advantage because millions of frontend developers that write JavaScript for the browser are now able to write the server-side code in addition to the client-side code without the need to learn a completely different language. In Node.js the new ECMAScript standards can be used without problems, as you don't have to wait for all your users to update their browsers - you are in charge of deciding which ECMAScript version to use by changing the Node.js version, and you can also enable specific experimental features by running Node.js with flags. A Vast Number of Libraries npm with its simple structure helped the ecosystem of Node.js proliferate, and now the npm registry hosts over 1,000,000 open source packages you can freely use. An Example Node.js Application The most common example Hello World of Node.js is a web server: This code first includes the Node.js http module. Node.js has a fantastic standard library, including first-class support for networking. The createServer() method of http creates a new HTTP server and returns it. The server is set to listen on the specified port and host name. When the server is ready, the callback function is called, in this case informing us that the server is running. Whenever a new request is received, the request event is called, providing two objects: a request (an http.IncomingMessage object) and a response (an http.ServerResponse object). Those 2 objects are essential to handle the HTTP call. The first provides the request details. In this simple example, this is not used, but you could access the request headers and request data. The second is used to return data to the caller. In this case with: res.statusCode = 200; we set the statusCode property to 200, to indicate a successful response. We set the Content-Type header: res.setHeader('Content-Type', 'text/plain'); and we close the response, adding the content as an argument to end(): res.end('Hello World\n'); Node.js Frameworks and Tools Node.js is a low-level platform. In order to make things easy and exciting for developers, thousands of libraries were built upon Node.js by the community. Many of those established over time as popular options. Here is a non-comprehensive list of the ones worth learning: AdonisJs: A full-stack framework highly focused on developer ergonomics, stability, and confidence. Adonis is one of the fastest Node.js web frameworks. Express: It provides one of the most simple yet powerful ways to create a web server. Its minimalist approach, unopinionated, focused on the core features of a server, is key to its success. Fastify: A web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. Fastify is one of the fastest Node.js web frameworks. Gatsby: A React-based, GraphQL powered, static site generator with a very rich ecosystem of plugins and starters. hapi: A rich framework for building applications and services that enables developers to focus on writing reusable application logic instead of spending time building infrastructure. koa: It is built by the same team behind Express, aims to be even simpler and smaller, building on top of years of knowledge. The new project born out of the need to create incompatible changes without disrupting the existing community. Loopback.io: Makes it easy to build modern applications that require complex integrations. Meteor: An incredibly powerful full-stack framework, powering you with an isomorphic approach to building apps with JavaScript, sharing code on the client and the server. Once an off-the-shelf tool that provided everything, now integrates with frontend libs React, Vue, and Angular. Can be used to create mobile apps as well. Micro: It provides a very lightweight server to create asynchronous HTTP microservices. NestJS: A TypeScript based progressive Node.js framework for building enterprise-grade efficient, reliable and scalable server-side applications. Next.js: React framework that gives you the best developer experience with all the features you need for production: hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and more. Nx: A toolkit for full-stack monorepo development using NestJS, Express, React, Angular, and more! Nx helps scale your development from one team building one application to many teams collaborating on multiple applications! Sapper: Sapper is a framework for building web applications of all sizes, with a beautiful development experience and flexible filesystem-based routing. Offers SSR and more! Socket.io: A real-time communication engine to build network applications. Strapi: Strapi is a flexible, open-source Headless CMS that gives developers the freedom to choose their favorite tools and frameworks while also allowing editors to easily manage and distribute their content. By making the admin panel and API extensible through a plugin system, Strapi enables the world's largest companies to accelerate content delivery while building beautiful digital experiences.
    https://bgoonz-blog.netlify.app/images/code.png
  • Install
    Close Menu Install Node.js can be installed in different ways. This post highlights the most common and convenient ones. Official packages for all the major platforms are available at https://nodejs.org/en/download/. One very convenient way to install Node.js is through a package manager. In this case, every operating system has its own. On macOS, Homebrew is the de-facto standard, and - once installed - allows you to install Node.js very easily, by running this command in the CLI: brew install node Other package managers for Linux and Windows are listed in https://nodejs.org/en/download/package-manager/ nvm is a popular way to run Node.js. It allows you to easily switch the Node.js version, and install new versions to try and easily rollback if something breaks, for example. It is also very useful to test your code with old Node.js versions. See https://github.com/creationix/nvm for more information about this option. My suggestion is to use the official installer if you are just starting out and you don't use Homebrew already, otherwise, Homebrew is my favorite solution. In any case, when Node.js is installed you'll have access to the node executable program in the command line. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    The HTTP Protocol The HTTP Protocol Requires: a connection between client and server Stateless: no login process, each request is independent Simple format: request header, blank line, possible payload Symmetrical: allows data to be sent and recieved Very easy to implement but scales very well Example HTTP Request Note lines folded for display. What do each of these headers mean? Which are required? Many are defined in the HTTP standard but others can be defined via the HTTP extension framework. Example HTTP Response Example HTTP POST Request Note lines folded for display. This is a POST request, note how the data is encoded in the request body. Example HTTP GET Request Note lines folded for display. This is the same form submitted via a GET request, here the data is encoded in request URL. Note also the If-Modified-Since header in this request, sent because my browser has just asked for the same resource. HTTP Redirect Alternately The HTTP redirect is a server response that can be used to indicate that a resource has moved to a new location. An alternate is to include the above meta tag in a page header to force a redirect from the current page. HTTP Verbs GET - get a resource, Idempotent POST - send some data to a resource HEAD - get headers for a resource PUT - create a new resource DELETE - delete a resource Common HTTP Response Status Codes Some notable response codes: 200 OK - Request succeeded and everything went well 301 Moved Permanently - Requested resource has moved and all future requests should be made to new location 403 Forbidden - Response refused by server (even if request is valid) 404 Not Found - Server could not find requested resource (though it may be available in the future) 500 Internal Server Error - Generic error message response when server encountered an error See also: full list of HTTP status codes Resources Use Live HTTP Headers in Firefox to view headers of requests that you make. Also available as a Chrome Extension. Similarly, in Google Chrome, the Resources panel in the Developer tools allows you to view the request headers and content for each request that was made when you're looking at a page. Wikipedia's entry on HTTP gives a good overview of the protocol.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    How The Web Works What is the World Wide Web? Perhaps the first thing to establish in our discussion of the web is what exactly it is. This chapter will look in brief overview at the core technologies that go together to make the World Wide Web. We can start by differentiating the Internet and the World Wide Web. These are often confused because the Web is the main use that most people have for the Internet and a common web browser is called "Internet Explorer". However, we can properly distinguish between them. The Internet is a collection of inter-connected computers using the TCP/IP protocol to exchange information. The World Wide Web is a particular use of the Internet to exchange HTML web pages (and other documents) using the Hypertext Transfer Protocol (HTTP). Let's look briefly at the four basic ingredients of the Web: TCP/IP - is a low level message protocol that is used to transfer messages between computers on the Internet. HTTP - is used by a Web Client to make a request to a Web Server and for the server to return the response. URL - is a way of writing down the address of something on the Web so that a browser can work out where to get it from. HTML - is a language for writing web pages containing text, images and other content. Together, these four technologies allow a web client - the web browser on your computer - to fetch pages from a web server anywhere in the world that might contain links to other documents and so on. It's the links between documents that make this a Web and the Internet that allows it to be the World Wide Web. Let's look at each of these technologies in a little more detail; although we'll explore most of them a lot more throughout the rest of this book. TCP/IP and DNS TCP/IP, the Transmission Control Protocol/Internet Protocol, is the standard way of exchanging messages on the Internet - in fact it effectively defines what the Internet is: a network of computers communicating via TCP/IP. For our purposes, there's no need to have a deep understanding of the low level details of TCP/IP, though many of you will learn more about it if you study any networking topics. However there are a few higher level things that touch on how we use the Internet in the context of the World Wide Web. A Protocol in this sense is a formal standard for how two machines will talk to each other over a communications channel. It describes what messages are allowed and what they mean and how data is transferred over the network. Later, we'll look at HTTP which is a higher level protocol for web requests. TCP/IP deals with the low level exchange of data and doesn't really care what the content of that data is. The Internet is a collection of computer networks joined by physical network channels. Within an organisation, there may be a physical network based on the Ethernet standard (wired or wireless) which effectively connects all computers on the network to each other. Organisations connect to each other via DSL or cable connections. These inter-connected net works make up the Internet. The role of TCP/IP is to allow a computer within one organisation (your laptop) to establish a connection to a computer in another (a web server). Importantly, this connection is a point-to-point connection - like a private channel between the two computers, even though the data is carried by this shared network of networks. TCP/IP is a packet oriented protocol. To send a message, it is broken up into small chunks (packets) which are each addressed and sent over the network. The receiving computer intercepts these packets, notices that they are addressed to them, and re-assembles the original message. Packets can arrive out of order (or not at all) and TCP/IP defines what the two communicating computers should do in this case. Each computer on the network is assigned a unique IP address which is a 32 bit number usually expressed as four 8 bit digits separated by dots. For example 192.168.1.2 or 137.111.158.22. These numbers are used as the addresses of the packets sent around the Internet. Within an organisation, all computers will share the first part of their address; for example, all Macquarie University computers will have addresses starting with 137.111. This means that any packet sent from within Macquarie to an address in the range 137.111.x.x will find it's destination somewhere inside the organisation. However, if we send a packet to 143.119.160.16 (the NSW Government website) the network protocols need to know that this packet should be forwarded to the NSW Government network before it can be delivered. We can pretend that this all happens by magic (this isn't a networking course) and rest assured that a clever network routing algorithm will get the packets to where they need to go. As long as we know the IP address of the destination computer, we can establish a point-to-point channel and send data back and forth. Within your home you might have your own private network, often established by a wireless router that connects to your ADSL or cable service. While this router will have a proper IP address, the network it establishes in your home is a private network and will use one of two address ranges: 192.168.x.x or 10.10.x.x. Both of these are reserved for private use, so that my laptop and your printer might have the same IP address of 192.168.100.13. A trick called Network Address Translation (NAT) carried out by your router allows each of these devices to connect to the Internet through the router, even though they don't have a full IP address. Again, we don't need to worry about the details but sometimes it's useful to know how to communicate directly with devices on your own network, in which case you might start finding out about these private IP addresses. A significant issue with the success and ubiquity of the Internet is that we might run out of unique addresses. Since an IP address is a 32 bit number, that means there are only 4,294,967,296 unique addresses. If every computer, mobile phone, printer and electricity meter is to be connected to the Internet, the it's clear that more addresses will be needed. There are two responses to this. The first is that many of these devices share a single IP address (using NAT) which multiplies the number available significantly. THe second is a new standard called IPv6 (rather than IPv4 which I've described here) where addresses are 128 bits long. Most modern devices are able to use IPv6 addressing so the crisis is unlikely to hit us catastrophically. IP addresses give a unique identifier for each device but they aren't very easy to remember. We're used to giving the names of web-sites via names like www.nsw.gov.au or sales.example.com. These names are translated into numerical IP addresses via the Domain Name System (DNS) which works using a clever hierarchical algorithm. For example, to work out what sales.example.com means our local DNS server would look at the last part of the address and forward the query to a server that it knows is authoritative for all addresses ending in .com. The .com server may not know which IP address corresponds to sales.example.com so it sends the query on to the DNS server for example.com which will respond with the answer. As the result is passed back to the original DNS server, it is cached (remembered) so that it can be returned more quickly the next time it is requested. DNS allows an organisation to set up whatever names it needs and link those names to its servers. It's common to have the main web server called www.example.com but the same server could also be referred to as example.com, sales.example.com or test.example.com. We'll see later how this arrangement can be used to provide a lot of flexibility when setting up web servers. HTTP In 1991 Tim Berners-Lee invented the World Wide Web. He was building on the existing technology of the Internet that allowed computers to exchange information around the world. His invention consisted essentially of three things: the Hypertext Transfer Protocol (HTTP), the Universal Resource Locator (URL) and the Hypertext Markup Language (HTML). HTTP is the language that a web client (your browser) talks to a web server to ask for a page and get the response back. It's a protocol, just like TCP/IP, but it's a much higher level protocol and it's one that we need to understand very well as web programmers. HTTP requires that we first establish a point-to-point connection between a client (who is sending a request) and a server (who will fulfil the request if possible). This connection is usually via TCP/IP over the Internet but could also be over any other communication medium such as bluetooth. Once the connection is established, the conversation can begin. One of the important features of HTTP is that it is a simple, text based protocol. The request and response consist of a number of lines of text in a well defined format. Here is an example request that might be sent to a server: The first word in the request is always one of the defined HTTP verbs (most frequently GET, HEAD or POST, we'll explore these in more detail later). A GET request asks the server to return the given resource, in this case '/storefront.html' which is probably an HTML file stored somewhere on the server. The last part of the first line (HTTP/1.1) defines the version of the standard that we are using; there was a version 1.0 but most modern browsers will use 1.1. The remaining lines of the request include other headers that qualify the request in some way. The Host header is required and denotes the server that the request is being sent to. The Accept header defines what kinds of document we'd like in return; in this case, any kind of text document is ok. The request ends with a blank line, which is how the server knows that all headers have been received. The request is received and processed by the server and a response is sent back to the client containing the web page that was asked for. Again the format of the response is easy to understand: The first word of the response must be HTTP/1.1, the remainder of the first line contains a response code (200) and explanation (OK) in this case saying everything is fine, here's the page you asked for. The second header here defines the type of document being returned (it's an HTML page). There is then a blank line which ends the headers (as with the request) and the HTML content is then sent. A real request and response pair will have many more headers than this but their format follows this basic pattern: header lines followed by a blank line and an optional body. The point here is that HTTP is a very simple conversation between web client and server. One important feature of HTTP is that each request/response pair is independent of every other. This means that all the information about your request must be included in the request headers; the server doesn't remember anything you told it last time. This is one reason that HTTP and the web have been so successful. It is very easy to implement an HTTP server and it can be done on very small devices. This might be one of the reasons why the Web succeeded where other similar systems failed. Since the protocol is so simple, it was easy to write a web server and many people did. This meant that the web was used by many small groups to publish content, forming the groundswell that led to institutional and corporate adoption. We'll look at HTTP in more detail later, for now the take home message is: HTTP is a simple text based protocol The client (browser) sends a request to the server The server receives the request and returns a response The server doesn't need to remember the client - every request is independant. The simple nature of HTTP makes it easy to understand and makes writing web servers relatively easy. Uniform Resource Locators: URL Another part of Tim Berners-Lee's invention is the Uniform Resource Locator, URL. These days, URLs are ubiquitous. We see them on advertisments, on the TV, we send them to each other in email, even reference them in books and reports. Most organisations today will have at least one top-level URL for their website and often have many connected to particular services, departments or advertising campaigns. See the URL chapter for a detaile discussion. Hypertext Markup Language: HTML HTML is the last link in the chain that makes the Web. It is a language that allows authors to write Hypertext documents that include structure and formatting instructions. Hypertext describes the idea of linking one document to another via hyperlinks so that when you activate a link, you jump to a new document. There were hypertext systems before the birth of the web ( Project Xanadu, Hypercard) but HTML has been much more successful than any other standard in this space. HTML is a Markup Language which means that it provides a way of adding additional information or markup to plain text. In this case, the markup defines the structure of the document - headers, paragraphs, lists, tables - as well as the hypertext features - links and anchors. There are other markup languages, for example LaTeX is used to write scientific papers by adding markup to text (e.g. \textbf{bold text} or \section{A heading}). All markup languages have some way of differentiating the text in a document from the markup instructions. In HTML this is via the angle brackets which surround tag names: <tag>. HTML was invented by Tim Berners-Lee but it derives from an earlier standard called SGML (Standard Generalised Markup Language) that had been in use for some years as a language for writing technical documentation. It came out of work by IBM on their technical documentation and became an industry standard ratified by the ISO. SGML is in fact a meta-standard in that it defines a way of defining a markup language. HTML is one such markup language and can strictly be treated as such; however, since HTML is so much more common than any other SGML language, it is usually treated as a special case. So, for example, while we could use general purpose SGML authoring tools to write HTML, we generally use applications tailored to writing web pages that only understand HTML. Another related markup language is XML, the eXtensible Markup Language. XML began as an attempt to streamline the SGML standard to make it more suitable for the web. Like SGML, XML is a meta-standard that defines how markup languages can be written. There is a version of HTML defined as an XML language called XHTML but this never really took off and the standardisation work around it was stopped in 2010. Instead, XML has become widely used to describe data rather than documents and we'll look at how it is used today on the web later in this book.
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Fs-Module The fs module provides a lot of very useful functionality to access and interact with the file system. There is no need to install it. Being part of the Node.js core, it can be used by simply requiring it: const fs = require('fs'); Once you do so, you have access to all its methods, which include: fs.access(): check if the file exists and Node.js can access it with its permissions fs.appendFile(): append data to a file. If the file does not exist, it's created fs.chmod(): change the permissions of a file specified by the filename passed. Related: fs.lchmod(), fs.fchmod() fs.chown(): change the owner and group of a file specified by the filename passed. Related: fs.fchown(), fs.lchown() fs.close(): close a file descriptor fs.copyFile(): copies a file fs.createReadStream(): create a readable file stream fs.createWriteStream(): create a writable file stream fs.link(): create a new hard link to a file fs.mkdir(): create a new folder fs.mkdtemp(): create a temporary directory fs.open(): set the file mode fs.readdir(): read the contents of a directory fs.readFile(): read the content of a file. Related: fs.read() fs.readlink(): read the value of a symbolic link fs.realpath(): resolve relative file path pointers (., ..) to the full path fs.rename(): rename a file or folder fs.rmdir(): remove a folder fs.stat(): returns the status of the file identified by the filename passed. Related: fs.fstat(), fs.lstat() fs.symlink(): create a new symbolic link to a file fs.truncate(): truncate to the specified length the file identified by the filename passed. Related: fs.ftruncate() fs.unlink(): remove a file or a symbolic link fs.unwatchFile(): stop watching for changes on a file fs.utimes(): change the timestamp of the file identified by the filename passed. Related: fs.futimes() fs.watchFile(): start watching for changes on a file. Related: fs.watch() fs.writeFile(): write data to a file. Related: fs.write() One peculiar thing about the fs module is that all the methods are asynchronous by default, but they can also work synchronously by appending Sync. For example: fs.rename() fs.renameSync() fs.write() fs.writeSync() This makes a huge difference in your application flow. Node.js 10 includes experimental support for a promise based API For example let's examine the fs.rename() method. The asynchronous API is used with a callback: const fs = require('fs'); fs.rename('before.json', 'after.json', (err) => { if (err) { return console.error(err); } //done }); A synchronous API can be used like this, with a try/catch block to handle errors: const fs = require('fs'); try { fs.renameSync('before.json', 'after.json'); //done } catch (err) { console.error(err); } The key difference here is that the execution of your script will block in the second example, until the file operation succeeded. Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    The Node.js Event Loop Introduction The Event Loop is one of the most important aspects to understand about Node.js. Why is this so important? Because it explains how Node.js can be asynchronous and have non-blocking I/O, and so it explains basically the "killer app" of Node.js, the thing that made it this successful. The Node.js JavaScript code runs on a single thread. There is just one thing happening at a time. This is a limitation that's actually very helpful, as it simplifies a lot how you program without worrying about concurrency issues. You just need to pay attention to how you write your code and avoid anything that could block the thread, like synchronous network calls or infinite loops. In general, in most browsers there is an event loop for every browser tab, to make every process isolated and avoid a web page with infinite loops or heavy processing to block your entire browser. The environment manages multiple concurrent event loops, to handle API calls for example. Web Workers run in their own event loop as well. You mainly need to be concerned that your code will run on a single event loop, and write code with this thing in mind to avoid blocking it. Blocking the event loop Any JavaScript code that takes too long to return back control to the event loop will block the execution of any JavaScript code in the page, even block the UI thread, and the user cannot click around, scroll the page, and so on. Almost all the I/O primitives in JavaScript are non-blocking. Network requests, filesystem operations, and so on. Being blocking is the exception, and this is why JavaScript is based so much on callbacks, and more recently on promises and async/await. The call stack The call stack is a LIFO queue (Last In, First Out). The event loop continuously checks the call stack to see if there's any function that needs to run. While doing so, it adds any function call it finds to the call stack and executes each one in order. You know the error stack trace you might be familiar with, in the debugger or in the browser console? The browser looks up the function names in the call stack to inform you which function originates the current call: A simple event loop explanation Let's pick an example: When this code runs, first foo() is called. Inside foo() we first call bar(), then we call baz(). At this point the call stack looks like this: The event loop on every iteration looks if there's something in the call stack, and executes it: until the call stack is empty. Queuing function execution The above example looks normal, there's nothing special about it: JavaScript finds things to execute, runs them in order. Let's see how to defer a function until the stack is clear. The use case of setTimeout(() => {}, 0) is to call a function, but execute it once every other function in the code has executed. Take this example: This code prints, maybe surprisingly: foo baz bar When this code runs, first foo() is called. Inside foo() we first call setTimeout, passing bar as an argument, and we instruct it to run immediately as fast as it can, passing 0 as the timer. Then we call baz(). At this point the call stack looks like this: Here is the execution order for all the functions in our program: Why is this happening? The Message Queue When setTimeout() is called, the Browser or Node.js starts the timer. Once the timer expires, in this case immediately as we put 0 as the timeout, the callback function is put in the Message Queue. The Message Queue is also where user-initiated events like click or keyboard events, or fetch responses are queued before your code has the opportunity to react to them. Or also DOM events like onLoad. The loop gives priority to the call stack, and it first processes everything it finds in the call stack, and once there's nothing in there, it goes to pick up things in the message queue. We don't have to wait for functions like setTimeout, fetch or other things to do their own work, because they are provided by the browser, and they live on their own threads. For example, if you set the setTimeout timeout to 2 seconds, you don't have to wait 2 seconds - the wait happens elsewhere. ES6 Job Queue ECMAScript 2015 introduced the concept of the Job Queue, which is used by Promises (also introduced in ES6/ES2015). It's a way to execute the result of an async function as soon as possible, rather than being put at the end of the call stack. Promises that resolve before the current function ends will be executed right after the current function. I find nice the analogy of a rollercoaster ride at an amusement park: the message queue puts you at the back of the queue, behind all the other people, where you will have to wait for your turn, while the job queue is the fastpass ticket that lets you take another ride right after you finished the previous one. Example: That's a big difference between Promises (and Async/await, which is built on promises) and plain old asynchronous functions through setTimeout() or other platform APIs.
    https://bgoonz-blog.netlify.app/images/code.png
  • Dev Dependencies
    Close Menu Dev Dependencies When you install an npm package using npm install <package-name>, you are installing it as a dependency. The package is automatically listed in the package.json file, under the dependencies list (as of npm 5: before you had to manually specify --save). When you add the -D flag, or --save-dev, you are installing it as a development dependency, which adds it to the devDependencies list. Development dependencies are intended as development-only packages, that are unneeded in production. For example testing packages, webpack or Babel. When you go in production, if you type npm install and the folder contains a package.json file, they are installed, as npm assumes this is a development deploy. You need to set the --production flag ( npm install --production) to avoid installing those development dependencies. Back to top
    https://bgoonz-blog.netlify.app/images/react2.jpg
  • Buffer
    Node Buffers What is a buffer? A buffer is an area of memory. JavaScript developers are not familiar with this concept, much less than C, C++ or Go developers (or any programmer that uses a system programming language), which interact with memory every day. It represents a fixed-size chunk of memory (can't be resized) allocated outside of the V8 JavaScript engine. You can think of a buffer like an array of integers, which each represent a byte of data. It is implemented by the Node.js Buffer class. Why do we need a buffer? Buffers were introduced to help developers deal with binary data, in an ecosystem that traditionally only dealt with strings rather than binaries. Buffers are deeply linked with streams. When a stream processor receives data faster than it can digest, it puts the data in a buffer. A simple visualization of a buffer is when you are watching a YouTube video and the red line goes beyond your visualization point: you are downloading data faster than you're viewing it, and your browser buffers it. How to create a buffer A buffer is created using the Buffer.from(), Buffer.alloc(), and Buffer.allocUnsafe() methods. const buf = Buffer.from('Hey!'); Buffer.from(array) Buffer.from(arrayBuffer[, byteOffset[, length]]) Buffer.from(buffer) Buffer.from(string[, encoding]) You can also just initialize the buffer passing the size. This creates a 1KB buffer: const buf = Buffer.alloc(1024); //or const buf = Buffer.allocUnsafe(1024); While both alloc and allocUnsafe allocate a Buffer of the specified size in bytes, the Buffer created by alloc will be initialized with zeroes and the one created by allocUnsafe will be uninitialized. This means that while allocUnsafe would be quite fast in comparison to alloc, the allocated segment of memory may contain old data which could potentially be sensitive. Older data, if present in the memory, can be accessed or leaked when the Buffer memory is read. This is what really makes allocUnsafe unsafe and extra care must be taken while using it. Using a buffer Access the content of a buffer A buffer, being an array of bytes, can be accessed like an array: const buf = Buffer.from('Hey!'); console.log(buf[0]); //72 console.log(buf[1]); //101 console.log(buf[2]); //121 Those numbers are the Unicode Code that identifies the character in the buffer position (H => 72, e => 101, y => 121) You can print the full content of the buffer using the toString() method: console.log(buf.toString()); Notice that if you initialize a buffer with a number that sets its size, you'll get access to pre-initialized memory that will contain random data, not an empty buffer! Get the length of a buffer Use the length property: const buf = Buffer.from('Hey!'); console.log(buf.length); Iterate over the contents of a buffer const buf = Buffer.from('Hey!'); for (const item of buf) { console.log(item); //72 101 121 33 } Changing the content of a buffer You can write to a buffer a whole string of data by using the write() method: const buf = Buffer.alloc(4); buf.write('Hey!'); Just like you can access a buffer with an array syntax, you can also set the contents of the buffer in the same way: const buf = Buffer.from('Hey!'); buf[1] = 111; //o console.log(buf.toString()); //Hoy! Copy a buffer Copying a buffer is possible using the copy() method: const buf = Buffer.from('Hey!'); let bufcopy = Buffer.alloc(4); //allocate 4 bytes buf.copy(bufcopy); By default you copy the whole buffer. 3 more parameters let you define the starting position, the ending position, and the new buffer length: const buf = Buffer.from('Hey!'); let bufcopy = Buffer.alloc(2); //allocate 2 bytes buf.copy(bufcopy, 0, 0, 2); bufcopy.toString(); //'He' Slice a buffer If you want to create a partial visualization of a buffer, you can create a slice. A slice is not a copy: the original buffer is still the source of truth. If that changes, your slice changes. Use the slice() method to create it. The first parameter is the starting position, and you can specify an optional second parameter with the end position: const buf = Buffer.from('Hey!'); buf.slice(0).toString(); //Hey! const slice = buf.slice(0, 2); console.log(slice.toString()); //He buf[1] = 111; //o console.log(slice.toString()); //Ho
    https://bgoonz-blog.netlify.app/images/javascript-4ced5a19.gif
  • Web-Dev-Hub
    Web Dev Review description: Review Review-Of-Previous-Concepts Review of Concepts Running JS Locally Concepts Match the commands ls, cd, pwd to their descriptions ls lists contents of current directory cd changes current directory cd .. takes you up one level cd alone takes you back home pwd returns current directory Given a folder structure diagram, a list of 'cd (path)' commands and target files, match the paths to the target files. Use VSCode to create a folder. Within the folder create a .js file containing console.log('hello new world'); and save it. Use node to execute a JavaScript file in the terminal Plain Old JS Object Lesson Concepts Label variables as either Primitive vs. Reference primitives: strings, booleans, numbers, null and undefined primitives are immutable refereces: objects (including arrays) references are mutable Identify when to use . vs [] when accessing values of an object dot syntax object.key easier to read easier to write cannot use variables as keys keys cannot begin with a number bracket notation object["key] allows variables as keys strings that start with numbers can be use as keys Write an object literal with a variable key using interpolation put it in brackets to access the value of the variable, rather than just make the value that string let a = 'b'; let obj = { a: 'letter_a', [a]: 'letter b' }; Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object can also use (key in object) syntax interchangeably (returns a boolean) Utilize Object.keys and Object.values in a function Object.keys(obj) returns an array of all the keys in obj Object.values(obj) returns an array of the values in obj Iterate through an object using a for in loop let printValues = function (obj) { for (let key in obj) { let value = obj[key]; console.log(value); } }; Define a function that utilizes ...rest syntax to accept an arbitrary number of arguments...rest syntax will store all additional arguments in an array array will be empty if there are no additional arguments let myFunction = function (str, ...strs) { console.log('The first string is ' + str); console.log('The rest of the strings are:'); strs.forEach(function (str) { console.log(str); }); }; Use ...spread syntax for Object literals and Array literals let arr1 = ['a', 'b', 'c']; let longer = [...arr1, 'd', 'e']; // ["a", "b", "c", "d", "e"] // without spread syntax, this would give you a nested array let withoutRest = [arr1, 'd', 'e']; // [["a", "b", "c"], "d", "e"] Destructure an array to reference specific elements```javascript let array = [35,9]; let [firstEl, secondEl] = array; console.log(firstEl); // => 35 console.log(secondEl); // => 9// can also destructure using ... syntax let array = [35,9,14]; let [head, ...tail] = array; console.log(head); // => 35 console.log(tail); // => [9, 14]- Destructure an object to reference specific values - if you want to use variable names that don't match the keys, you can use aliasing - `let { oldkeyname: newkeyname } = object` - rule of thumb—only destructure values from objects that are two levels deep ```javascript let obj = { name: "Wilfred", appearance: ["short", "mustache"], favorites: { color: "mauve", food: "spaghetti squash", number: 3 } } // with variable names that match keys let { name, appearance } = obj; console.log(name); // "Wilfred" console.log(appearance); // ["short", "mustache"] // with new variable names (aliasing) let {name: myName, appearance: myAppearance} = obj; console.log(myName); // "Wilfred" console.log(myAppearance); // ["short", "mustache"] // in a function call let sayHello = function({name}) { console.log("Hello, " + name); // "Hello Wilfred" } // nested objects + aliasing let { favorites: {color, food: vegetable} } = obj; console.log(color, vegetable); //=> mauve spaghetti squash Write a function that accepts a array as an argument and returns an object representing the count of each character in the array// let elementCounts = function (array) { let obj = {}; array.forEach(function (el) { if (el in obj) obj[el] += 1; else obj[el] = 1; }); return obj; }; console.log(elementCounts(['e', 'f', 'g', 'f'])); // => Object {e: 1, f: 2, g: 1} Callbacks Lesson Concepts Given multiple plausible reasons, identify why functions are called "First Class Objects" in JavaScript. they can be stored in variables, passed as arguments to other functions, and serve as return value for a function supports same basic operations as other types (strings, bools, numbers) higher-order functions take functions as arguments or return functions as values Given a code snippet containing an anonymous callback, a named callback, and multiple console.log s, predict what will be printed what is this referring to? Write a function that takes in a value and two callbacks. The function should return the result of the callback that is greater. let greaterCB = function (val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); }; let greaterCB = function (val, callback1, callback2) { if (callback1(val) > callback2(val)) { return callback1(val); } return callback2(val); }; // shorter version let greaterCB = function(val, callback1, callback2) { return Math.max(callback1(val), callback2(val)); } // even shorter, cause why not let greaterCB = (val, cb1, cb2) => Math.max(cb1(val), cb2(val));- Write a function, myMap, that takes in an array and a callback as arguments. The function should mimic the behavior of `Array#map`. ```javascript let myMap = function(array, callback) { let newArr = []; for (let i = 0; i < array.length; i ++) { mapped = callback(array[i], i, array); newArr.push(mapped); } return newArr; } console.log( myMap([16,25,36], Math.sqrt)); // => [4, 5, 6]; let myMapArrow = (array, callback) => { let newArr = []; array.forEach( (ele, ind, array) => { newArr.push(callback(ele, ind, array)); }) return newArr; } console.log(myMapArrow([16,25,36], Math.sqrt)); // => [4, 5, 6]; Write a function, myFilter, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#filter. let myFilter = function (array, callback) { let filtered = []; for (let i = 0; i < array.length; i++) { if (callback(array[i])) { filtered.push(array[i], i, array); } } }; Write a function, myEvery, that takes in an array and a callback as arguments. The function should mimic the behavior of Array#every. let myEvery = function (array, callback) { for (let i = 0; i < array.length; i++) { if (!callback(array[i], i, array)) { return false; } } return true; }; // with arrow function syntax let myEvery = (array, callback) => { for (let i = 0; i < array.length; i++) { if (!callback(array[i])) { return false; } } return true; }; Scope Lesson Concepts Identify the difference between const, let, and var declarations const - cannot reassign variable, scoped to block let - can reassign variable, scoped to block var - outdated, may or may not be reassigned, scoped to function. can be not just reassigned, but also redeclared! a variable will always evaluate to the value it contains regardless of how it was declared Explain the difference between const, let, and var declarations var is function scoped—so if you declare it anywhere in a function, the declaration (but not assignment) is "hoisted" so it will exist in memory as "undefined" which is bad and unpredictable var will also allow you to redeclare a variable, while let or const will raise a syntax error. you shouldn't be able to do that! const won't let you reassign a variable, but if it points to a mutable object, you will still be able to change the value by mutating the object block-scoped variables allow new variables with the same name in new scopes block-scoped still performs hoisting of all variables within the block, but it doesn't initialize to the value of undefined like var does, so it throws a specific reference error if you try to access the value before it has been declared if you do not use var or let or const when initializing, it will be declared as global—THIS IS BAD if you assign a value without a declaration, it exists in the global scope (so then it would be accessible by all outer scopes, so bad). however, there's no hoisting, so it doesn't exist in the scope until after the line is run Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining scope of a program means the set of variables that are available for use within the program global scope is represented by the window object in the browser and the global object in Node.js global variables are available everywhere, and so increase the risk of name collisions local scope is the set of variables available for use within the function when we enter a function, we enter a new scope includes functions arguments, local variables declared inside function, and any variables that were already declared when the function is defined (hmm about that last one) for blocks (denoted by curly braces {}, as in conditionals or for loops), variables can be block scoped inner scope does not have access to variables in the outer scope scope chaining—if a given variable is not found in immediate scope, javascript will search all accessible outer scopes until variable is found so an inner scope can access outer scope variables but an outer scope can never access inner scope variables Define an arrow function```javascript let arrowFunction = (param1, param2) => { let sum = param1 + param2; return sum;}// with 1 param you can remove parens around parameters let arrowFunction = param => { param += 1; return param; }// if your return statement is one line, you can use implied return let arrowFunction = param => param + 1;// you don't have to assign to variable, can be anonymous // if you never need to use it again param => param + 1;``` Given an arrow function, deduce the value of this without executing the code arrow functions are automatically bound to the context they were declared in unlike regular function which use the context they are invoked in (unless they have been bound using Function#bind) if you implement an arrow function as a method in an object the context it will be bound to is NOT the object itself, but the global context so you can't use an arrow function to define a method directly```javascript let obj = { name: "my object", unboundFunc: function () { return this.name;// this function will be able to be called on different objects}, boundToGlobal: () => { return this.name; // this function, no matter how you call it, will be called // on the global object, and it cannot be rebound // this is because it was defined using arrow syntax }, makeFuncBoundToObj: function () { return () => { return this.name; } // this function will return a function that will be bound // to the object where we call the outer method // because the arrow syntax is nested inside one of this // function's methods, it cannot be rebound }, makeUnboundFunc: function () { return function () { return this.name; } //this function will return a function that will still be unbound }, immediatelyInvokedFunc: function () { return this.name; }(), // this property will be set to the return value of this anonymous function, // which is invoked during the object definition; // basically, it's a way to check the context inside of an object, at this moment innerObj: { name: "inner object", innerArrowFunc: () => { return this.name; } // the context inside a nested object is not the parent, it's still // the global object. entering an object definition doesn't change the context }, let otherObj = { name: "my other object" } // call unboundFunc on obj, we get "my object" console.log("unboundFunc: ", obj.unboundFunc()); // => "my object" // assign unboundFunc to a variable and call it let newFunc = obj.unboundFunc; // this newFunc will default to being called on global object console.log("newFunc: ",newFunc()); // => undefined // but you could bind it directly to a different object if you wanted console.log("newFunc: ", newFunc.bind(otherObj)()); // "my other object" // meanwhile, obj.boundToGlobal will only ever be called on global object console.log("boundToGlobal: ", obj.boundToGlobal()); //=> undefined let newBoundFunc = obj.boundToGlobal; console.log("newBoundFunc: ", newBoundFunc()); // => undefined // even if you try to directly bind to another object, it won't work! console.log("newBoundFunc: ", newBoundFunc.bind(otherObj)()); // => undefined // let's make a new function that will always be bound to the context // where we call our function maker let boundFunc = obj.makeFuncBoundToObj();// note that we're invoking, not just assigning console.log("boundFunc: ", boundFunc()); // => "my object" // we can't rebind this function console.log("boundFunc: ", boundFunc.bind(otherObj)()) // =>"my object" // but if I call makeFuncBoundToObj on another context // the new bound function is stuck with that other context let boundToOther = obj.makeFuncBoundToObj.bind(otherObj)(); console.log("boundToOther: ", boundToOther()); // => "my other object" console.log("boundToOther: ", boundToOther.bind(obj)()) // "my other object" // the return value of my immediately invoked function // shows that the context inside of the object is the // global object, not the object itself // context only changes inside a function that is called // on an object console.log("immediatelyInvokedFunc: ", obj.immediatelyInvokedFunc); // => undefined // even though we're inside a nested object, the context is // still the same as it was outside the outer object // in this case, the global object console.log("innerArrowFunc: ", obj.innerObj.innerArrowFunc()); // => undefined }- Implement a closure and explain how the closure effects scope - a closure is "the combination of a function and the lexical environment within which that function was declared" - alternatively, "when an inner function uses or changes variables in an outer function" - closures have access to any variables within their own scope + scope of outer functions + global scope — the set of all these available variables is "lexical environemnt" - closure keeps reference to all variables **even if the outer function has returned** - each function has a private mutable state that cannot be accessed externally - the inner function will maintain a reference to the scope in which it was declared. so it has access to variables that were initialized in any outer scope—even if that scope - if a variable exists in the scope of what could have been accessed by a function (e.g. global scope, outer function, etc), does that variable wind up in the closure even if it never got accessed? - if you change the value of a variable (e.g. i++) you will change the value of that variable in the scope that it was declared in ```javascript function createCounter() { // this function starts a counter at 0, then returns a // new function that can access and change that counter // // each new counter you create will have a single internal // state, that can be changed only by calling the function. // you can't access that state from outside of the function, // even though the count variable in question is initialized // by the outer function, and it remains accessible to the // inner function after the outer function returns. let count = 0; return function() { count ++; return count; } } let counter = createCounter(); console.log(counter()); //=> 1 console.log(counter()); //=> 2 // so the closure here comes into play because // an inner function is accessing and changing // a variable from an outer function // the closure is the combination of the counter // function and the all the variables that existed // in the scope that it was declared in. because // inner blocks/functions have access to outer // scopes, that includes the scope of the outer // function. // so counter variable is a closure, in that // it contains the inner count value that was // initialized by the outer createCounter() function // count has been captured or closed over // this state is private, so if i run createCounter again // i get a totally separate count that doesn't interact // with the previous one and each of the new functions // will have their own internal state based on the // initial declaration in the now-closed outer function let counter2 = createCounter(); console.log(counter2()); // => 1 // if i set a new function equal to my existing counter // the internal state is shared with the new function let counter3 = counter2; console.log(counter3()); Define a method that references this on an object literal when we use this in a method it refers to the object that the method is invoked on it will let you access other pieces of information from within that object, or even other methods method style invocation - object.method(args) (e.g. built in examples like Array#push, or String#toUpperCase) context is set every time we invoke a function function style invocation sets the context to the global object no matter what being inside an object does not make the context that object! you still have to use method-style invocation Utilize the built in Function#bind on a callback to maintain the context of this when we call bind on a function, we get an exotic function back—so the context will always be the same for that new function let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function // we can use the built in Function.bind to ensure our context, our this, // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints "meow" `` - `bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context. the first arg will be the context aka the `this` you want it to use. the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope (which itself has pointers to new scopes until you reach the global scope. so you can think about a whole given block's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function - so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object's method on something other than that object, and then this would refer to the context where/how it was called, e.g. ```javascript let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; // note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined // our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn't exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object let cat = { purr: function () { console.log("meow"); }, purrMore: function () { this.purr(); }, }; global.setTimeout(cat.purrMore, 5000); // 5 seconds later: TypeError: this.purr is not a function we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined let sayMeow = cat.purrMore; console.log(sayMeow()); // TypeError: this.purr is not a function// we can use the built in Function.bind to ensure our context, our this, // is the cat object let boundCat = sayMeow.bind(cat); boundCat(); // prints "meow" - `bind` can also work with arguments, so you can have a version of a function with particular arguments and a particular context. the first arg will be the context aka the `this` you want it to use. the next arguments will be the functions arguments that you are binding - if you just want to bind it to those arguments in particular, you can use `null` as the first argument, so the context won't be bound, just the arguments - Given a code snippet, identify what `this` refers to - important to recognize the difference between scope and context - scope works like a dictionary that has all the variables that are available within a given block, plus a pointer back the next outer scope (which itself has pointers to new scopes until you reach the global scope. so you can think about a whole given block's scope as a kind of linked list of dictionaries) (also, this is not to say that scope is actually implemented in this way, that is just the schema that i can use to understand it) - context refers to the value of the `this` keyword - the keyword `this` exists in every function and it evaluates to the object that is currently invoking that function - so the context is fairly straightforward when we talk about methods being called on specific objects - you could, however, call an object's method on something other than that object, and then this would refer to the context where/how it was called, e.g. ```javascript let dog = { name: "Bowser", changeName: function () { this.name = "Layla"; }, }; // note this is **not invoked** - we are assigning the function itself let change = dog.changeName; console.log(change()); // undefined // our dog still has the same name console.log(dog); // { name: 'Bowser', changeName: [Function: changeName] } // instead of changing the dog we changed the global name!!! console.log(this); // Object [global] {etc, etc, etc, name: 'Layla'} CALLING SOMETHING IN THE WRONG CONTEXT CAN MESS YOU UP! could throw an error if it expects this to have some other method or whatever that doesn't exist you could also overwrite values or assign values to exist in a space where they should not exist if you call a function as a callback, it will set this to be the outer function itself, even if the function you were calling is a method that was called on a particular object```javascript let cat = { purr: function () { console.log("meow");}, purrMore: function () { this.purr();},}; global.setTimeout(cat.purrMore, 5000); // 5 seconds later: TypeError: this.purr is not a function``` we can use strict mode with "use strict"; this will prevent you from accessing the global object with this in functions, so if you try to call this in the global context and change a value, you will get a type error, and the things you try to access will be undefined POJOs 1. Label variables as either Primitive vs. Reference Javascript considers most data types to be 'primitive', these data types are immutable, and are passed by value. The more complex data types: Array and Object are mutable, are considered 'reference' data types, and are passed by reference. Boolean - Primitive Null - Primitive Undefined - Primitive Number - Primitive String - Primitive Array - Reference Object - Reference Function - Reference 2. Identify when to use . vs [] when accessing values of an object let obj = { one: 1, two: 2 }; // Choose the square brackets property accessor when the property name is determined at // runtime, or if the property name is not a valid identifier let myKey = 'one'; console.log(obj[myKey]); // Choose the dot property accessor when the property name is known ahead of time. console.log(obj.two); 3. Write an object literal with a variable key using interpolation let keyName = 'two'; // If the key is not known, you can use an alternative `[]` syntax for // object initialization only let obj2 = { [keyName]: 2 }; console.log(obj2); 4. Use the obj[key] !== undefined pattern to check if a given variable that contains a key exists in an object function doesKeyExist(obj, key) { // obj[key] !== undefined // or: return key in obj; } let course = { bootcamp: 'Lambda', course: 'Bootcamp Prep' }; console.log(doesKeyExist(course, 'course')); // => true console.log(doesKeyExist(course, 'name')); // => false 5. Utilize Object.keys and Object.values in a function function printKeys(object) { return Object.keys(object); } function printValues(object) { return Object.values(object); } console.log(printKeys({ dog: 'Strelka', dog2: 'Belka' })); console.log(printValues({ dog: 'Strelka', dog2: 'Belka' })); 6. Iterate through an object using a for in loop let player = { name: 'Sergey', skill: 'hockey' }; for (let key in player) { console.log(key, player[key]); } console.log(Object.entries(player)); 7. Define a function that utilizes ...rest syntax to accept an arbitrary number of arguments function restSum(...otherNums) { let sum = 0; console.log(otherNums); otherNums.forEach(function (num) { sum += num; }); return sum; } console.log(restSum(3, 5, 6)); // => 14 console.log(restSum(1, 2, 3, 4, 5, 6, 7, 8, 9)); // => 45 console.log(restSum(0)); // => 0 8. Use ...spread syntax for Object literals and Array literals let numArray = [1, 2, 3]; let moreNums = [...numArray, 4, 5, 6]; console.log(moreNums); let shoe = { color: 'red', size: 10 }; let newShoe = { ...shoe, brand: 'Nike', size: 12 }; console.log(newShoe); newShoe.color = 'black'; console.log(newShoe); console.log(shoe); 9. Destructure an array to reference specific elements let arr = ['one', 'two', 'three']; let [first] = arr; console.log(first); 10. Destructure an object to reference specific values let me = { name: 'Ian', instruments: ['bass', 'synth', 'guitar'], siblings: { brothers: ['Alistair'], sisters: ['Meghan'] } }; let { name, instruments: musical_instruments, siblings: { sisters } } = me; console.log(name); console.log(musical_instruments); console.log(sisters); 11. Write a function that accepts a string as an argument and returns an object representing the count of each character in the array function charCount(inputString) { let res = inputString.split('').reduce(function (accum, el) { if (el in accum) { accum[el] = accum[el] + 1; } else { accum[el] = 1; } return accum; }, {}); return res; } console.log(charCount('aaabbbeebbcdkjfalksdfjlkasdfasdfiiidkkdingds')); Review of Concepts 1. Identify the difference between const, let, and var declarations 2. Explain the difference between const, let, and var declarations var a = 'a'; var is the historical keyword used for variable declaration. var declares variables in function scope, or global scope if not inside a function. We consider var to be deprecated and it is never used in this course. let b = 'b'; let is the keyword we use most often for variable declaration. let declares variables in block scope. variables declared with let are re-assignable. const c = 'c'; const is a specialized form of let that can only be used to initialize a variable. Except when it is declared, you cannot assign to a const variable. const scopes variables the same way that let does. 3. Predict the evaluation of code that utilizes function scope, block scope, lexical scope, and scope chaining Consider this run function, inside which foo and bar have function scope. i and baz are scoped to the block expression.// function and block scope in this example function run() { var foo = 'Foo'; let bar = 'Bar'; console.log(foo, bar); { console.log(foo); let baz = 'Bazz'; console.log(baz); } console.log(baz); // ReferenceError } run(); Notice that referencing baz from outside it's block results in JavaScript throwing a ReferenceError. Consider this run function, inside of which foo has function scope. function run() { console.log(foo); // undefined var foo = 'Foo'; console.log(foo); // Foo } run(); Consider this func1 function and it's nested scopes.// global scope function func1(arg1) { // func1 scope return function func2(arg2) { // func2 scope return function func3(arg3) { // func3 scope console.log(arg1, arg2, arg3); }; }; } 6. Implement a closure and explain how the closure effects scope const adder = (arg1) => { return (arg2) => { return arg1 + arg2; }; }; const func2 = adder(2); const result = func2(2); console.log(result); // => 4; 4. Define an arrow function const returnValue = (val) => val; This simple construct will create a function that accepts val as a parameter, and returns val immediately. We do not need to type return val, because this is a single-line function. Identically, we could write const returnValue = (val) => { return val; }; 5. Given an arrow function, deduce the value of this without executing the code function fDAdder(arr) { console.log(this); return arr.reduce((acc, ele) => { return acc + ele; }); } fDAdder([1, 2, 4, 6]); If we use a function declaration style function, the this variable is set to the global object (i.e. Object [global] in Node.JS and Window in your browser). const adder = (arr) => { console.log(this); arr.reduce((acc, ele) => (sum += ele)); }; adder([1, 2, 4, 6]); In this example, we use a fat arrow style function. Note that when we declare a funciton like this this becomes 7. Define a method that references this on an object literal const pokemon = { firstname: 'Pika', lastname: 'Chu', getPokeName: function () { const fullname = `${this.firstname} ${this.lastname}`; return fullname; } }; console.log(pokemon.getPokeName()); 8. Utilize the built in Function#bind on a callback to maintain the context of this const pokemon = { firstname: 'Pika', lastname: 'Chu', getPokeName: function () { const fullname = `${this.firstname} ${this.lastname}`; return fullname; } }; const logPokemon = pokemon.getPokename.bind(pokemon); logPokemon('sushi', 'algorithms'); // Pika Chu loves sushi and algorithms 9. Given a code snippet, identify what this refers to function Person(name) { // this.name = name; // let that = this; setTimeout(function () { // console.log(this); // => Window // console.log(that); // => [Function] => Person // this.sayName(); // => no method error that.sayName(); }, 1000); } Person.prototype.sayName = function () { console.log(this.name); }; const jane = new Person('Jane');
    https://bgoonz-blog.netlify.app/images/code.png
  • Resume
    Resume➤ Technical Skills­­­ Programming** Languages:** JavaScript ES-6, NodeJS, React, HTML5, CSS3, SCSS, Bash Shell, Excel, SQL, NoSQL, MATLAB, Python, C++ Databases: PostgreSQL, MongoDB Cloud: Docker, AWS, Google App Engine, Netlify, Digital Ocean, Heroku, Azure Cloud Services OS: Linux, Windows (WSL), IOS Agile: GitHub, BitBucket, Jira, Confluence IDEs: VSCode, Visual Studio, Atom, Code Blocks, Sublime Text 3, Brackets➤ Experience Relational Concepts: Hallandale Beach, FL March 2020 - Present Front End Web Developer Responsible for front-end development for a custom real estate application which provides sophisticated and fully customizable filtering to allow investors and real estate professionals to narrow in on exact search targets. Designed mock-up screens, wireframes, and workflows for intuitive user experience. Migrated existing multi-page user experience into singular page interfaces using React components. Participated in every stage of the design from conception through development and iterative improvement. Produced user stories and internal documentation for future site development and maintenance. Implemented modern frameworks including Bootstrap and Font-Awesome to give the site an aesthetic overhaul. Managed all test deployments using a combination of Digital Ocean and Netlify. Produced unit tests using a combination of Mocha and Chai. Injected Google Analytics to capture pertinent usage data to produce an insightful dashboard experience. Environment: JavaScript, JQuery, React, HTML5 & CSS, Bootstrap, DOJO, Google Cloud, Bash Script Cembre: Edison, NJ Nov 2019 – Mar 2020 Product Development Engineer Converted client's product needs into technical specs to be sent to the development team in Italy. Reorganized internal file server structure. Conducted remote / in person system integration and product demonstrations. Presided over internal and end user software trainings in addition to producing the corresponding documentation. Served as the primary point of contact for troubleshooting railroad hardware and software in the North America. Environment: Excel, AutoCAD, PowerPoint, Word➤ Education**B.S. Electrical Engineering, TCNJ, ** Ewing NJ 2014 – 2019 Capstone Project – Team Lead Successfully completed and delivered a platform to digitize a guitar signal and perform filtering before executing frequency & time domain analysis to track a current performance against prerecorded performance. Implemented the Dynamic Time Warping algorithm in C++ and Python to autonomously activate or adjust guitar effect at multiple pre-designated section of performance. Environment: C++, Python, MATLAB, PureData
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Job Search Job Boards and The Hunt I can't imagine the kind of masochism it would take to enjoy the act of posting and daily maintenance on a job board…It's part of the… Job Boards and The Hunt I can't imagine the kind of masochism it would take to enjoy the act of posting and daily maintenance on a job board…It's part of the process that you've already invested so much of yourself in, so you should take pride in it; do a good job the first time around and you'll get where your going in the blink of an eye! A list of all of my articles to link to future posts You should probably skip this one… seriously it's just for internal use! bryanguner.medium.com Update(After The Interview): As a candidate, there are key next steps that you can and should after every interview to help you stand out. Send a thank you email within 24 business hours Do not miss this step! It takes less than five minutes and can make the difference between you and another candidate. It also keeps you fresh in your interviewers' memories. For example:‍ Hi (name), Thank you so much for taking the time to meet with me yesterday to discuss my candidacy for (role title). After learning more about (share one or two takeaways from the interview about the company/team's priorities), I'm even more excited to bring my skills in (1–3 relevant skills) to the team. I look forward to hearing from you about next steps, and if there is anything that I can clarify about my experience or qualifications for the (role title) position, please don't hesitate to reach out. Thank you for your consideration,(your name) Follow up Don't wait for the company to reach out to you! Be proactive in showing your interest by checking in to see where you stand in the process. If a company indicates a deadline by which you will hear back, and the deadline has passed, follow-up! Check your email and phone regularly ‍* *Don't ghost on a company at any stage in the process; make sure you add their domain to your safe senders list and respond to any messages within 24 hours.‍ Be prepared ‍* *You might be invited for another interview on short notice; review the description regularly so it doesn't slip from your memory, and keep brushing up on skills you may need for an interview (chances are, this won't be the only job you'll need them for anyway!) Here I will maintain a running list of applicable job boards and below I will go into detail about the niches they occupy and whatever I resource I have found to use them to your maximum advantage. ! Update (remote work edition): Arc We Work Remotely Skip The Drive Power to Fly Remote OK Remotive FlexJobs Dribble AngelList Remote.co JustRemote Virtual Vocations Pangian Working Nomads Jobspresso Outsourcely Landing.Jobs Authentic Jobs Stack Overflow Gun.io Idealist Fiverr Upwork Freelancer freelancermap List: General Boards Built In Stack Overflow angel.co The Ladders CrunchBoard Uncubed Technical.ly Dice Tech Careers Mashable Remote or Relocation Boards: We Work Remotely Relocate‍ Work From Home Jobs Remote Boards & Companies Spreadsheet Career Vault DS Boards: BigDataJobs Icrunchdata Analyticsjobs.co.uk Design Boards Behance UX Jobs Board Krop Software Development Honeypot.io GitHub BlablaDev Smashing Magazine arstechnica obs.37signals ycombinator jobs.slashdot.org http://angel.co/talent whitetruffle crunchboard I am intentionally not linking glassdoor because they have irritated me for the last time by insisting I provide a job review every time I want to access their content… (To the makers of glassdoor… HOW MANY TIMES A MONTH DO YOU THINK I CHANGE JOBS!!!!) I don't have 15 minutes to make up a job experience every time I want to read a review. Also here is a repo of compiled job search and interviewing resources: bgoonz/INTERVIEW-PREP-COMPLETE Your resume is your personal summary sheet. Your resume is the thing that gets your foot in the door. So, there's a few… github.com First off I am going to introduce a few different categories for those of you who are completely overwhelmed by the prospect of even selecting a job board let alone establishing a competitive presence on one. Here's a few catorizations I think are worth distinguishing for one and other. 1. Interpersonal Connections Seek to leverage the connections you have with people you know and companies you want to work with. I know that that's a violation of the premise of this article but without even feeling the need to provide quantitative proof; I can confidently assume that this is the most RO I efficient way to produce a desirable result. (Sorry introverts… 2020 may have been your year but this is our world. 😘) If personal connections don't come through, the next best thing is cold outreach ( best in terms of results…. personally I hate cold calling strangers and I am an extrovert.) Before or after submitting an application, identify 1–3 professionals to reach out to at the company to express interest in opportunities. Send a message to express interest and request an informational interview with the individual via LinkedIn, email, Twitter, or other available communication methods. If you hear back and the individual is willing to connect, confirm a day and time to conduct a preliminary interview. OR If you have yet to hear back after 3 business days, follow-up. Once you send off a message in step two, there are a variety of responses you may receive. Sometimes an individual will forward you along to someone who may be of better assistance, other times your message may be overlooked with no reply, and its possible (best case scenario) your request for a chat becomes an invitation to interview.### ***2. LinkedIn***. I am going to devote a lot of time to this one because it is the largest and most active of all the job board ecosystems… period… full stop regardless of your industry. LinkedIn now has almost 740 million members with over 55 million registered companies. (for comparison 12.3 million people visited Indeed in October, up 19.6 percent. Monster.com attracted 12.1 million people, and CareerBuilder.com attractedd 11.3 million in that same time) and LinkedIn is the most-used social media platform amongst Fortune 500 companies as it provides far more networking capabilities than pure recruitment. If you put your resume and skills on LinkedIn.com as a software Engineer, and state that you are open to new opportunities, you will be contacted by multiple recruiters, and if your skills are desirable possibly also directly by companies seeking to hire you. It's a developer's market; there's not enough people out there, especially in America. Here's my profile… feel free to connect… the larger your network the greater your exposure is to someone who works at your potential dream job. Bryan Guner - Web Developer - Freelance | LinkedIn View Bryan Guner's profile on LinkedIn, the world's largest professional community. Bryan has 5 jobs listed on their… www.linkedin.com Here's A Linkedin Checklist I will be using before I return to the job hunt! LinkedIn Personal and Contact Information: www.notion.so excerpt: Experience Section[ ] I have listed all professional roles included on my resume in this section and any that I had to cut from my resume for space[ ] I have written 2–4 power statements for each experience listed (okay to copy and paste from resume)[ ] My power statements for each experience are bulleted, not in paragraph form.[ ] I did list responsibilities in bullet point format (I did not leave in paragraph format)[ ] I did start each bullet point with an action verb and I did not use phrases such as: Assisted with... Worked on... Helped with... ( Solely responsible for... ok)[ ] I did describe past projects in past tense and current projects in present tense[ ] I did not use pronouns such as: “I,” “we,” “they, “you,” “me,” “us”[ ] Optional: Bootcamp student experience and projects can be listed under your experience section if you have no (or almost no) prior work experience.[ ] If I listed my Bootcamp student experience, my title is [name of program] Student (example: Data Science Student)[ ] I copied and pasted my Lambda projects in my student description and also included them in the Accomplishments section Do's: Spend a good portion of your time learning and reading. Your jobs teach you so much about an organization and the business. Follow business owners and senior managers, successful team leaders in large organizations, startup owners. You would be surprised how willing some otherwise busy executives are to rub elbows with veritable newcomers. They're not just doing this out of the kindness of their hearts, just like you… they have an ulterior motive. They are hoping to build goodwill with the incoming workforce in a bid to make their company more attractive to high quality candidates. If they give you any of their time…treat it like an interview. To leverage this information, (the trick is to constantly remind yourself to be on your game with speaking with them.) I do not care what your teacher's past have said… mark my words… *THERE IS MOST CERTAINLY SUCH A THING AS A STUPID QUESTION**…Anyone who tells you otherwise is either stupid themselves or just overcome with their own compassion (an admirable trait but ultimately a disservice to you the competitive job seeker).* How to Ask Great Questions In Brief The Problem Some professionals such as litigators, journalists and even doctors, are taught to ask questions… hbr.org Engage in networking. I would recommend finding and connecting with current attendee of any software development bootcamp. They're all (for the most part) programatically encouraged to connect network and engage in peer skill promotion (even if they have no idea of you skill level). If that weren't enough reason, all of them come from a cohort of other individuals being instructed to do the same. Once you have a few in your network other's will seek you out through Linkedin recommendations algorithm. Note to prospective employers please just skip the next few sentences and don't ask why…😅 Of the 214 people that vouched for me… I guestimate about only 80 actually know me in any respectable capacity, and of those, only probably 30 or so are familiar with my competency in the skills they endorsed. It all boils down to the strategies that bootcamps instill in their students. It's the polar opposite of a zero sum game and they're more than happy to exchange personal recommendations with you. They're also far more driven to consistently engage with other members of the linkedin ecosystem because they need to a network to help compensate for their lack of a four year degree and the connections you make in that time. Build your personal brand. Developing your brand will not only help you attract clients or recruits if you decide to start a business, but will also help you find great job opportunities. You can post anything you take pride in so long as it's fairly professional. Definitely make use of the featured section to showcase your work.### Don't: Don't Use LinkedIn's Default Headline LinkedIn automatically populates your headline with your current job title and company name. I hope it goes without saying… but as a rule avoid signaling to prospective employers the depths of your laziness by using any stock responses LinkedIn provides you. Don't Go Ham On Keyword Placment Placing keywords strategically into your LinkedIn profile is virtually the only way to ensure being flagged by search algorithms as a potential candidate.You could be forgiven for being tempted to heed the advice of your inner lizard brain, and just stuffing your profile with buzzwords but this will likely trigger a spam account checker and result in worse outcomes than the absence of said keywords. Why it matters¿ Are We Really All Connected by Just Six Degrees of Separation? Most of us are familiar with the concept of six degrees of separation — the idea is that anyone in the planet can be connected to anyone else in just six steps. So through just five other people, you're effectively connected to the Queen of England, Jim Belushi or even yo mamma. Back to the other Job Board Niches: 3. Traditional job boards. Dice.com, Monster.com, etc. They will not find you great jobs at technology companies; they may find you openings as a software engineer at other types of more traditional companies (for example, banks, retail chains, etc though. 4. Local-focused sites. The biggest is Craigslist, but there are others. Often great for contract work and opportunities you wouldn't have otherwise come across. 5. Freelancer websites. oDesk.com, Elance.com, etc. Lower pay, but 100% contract work, and has a lot of flexible opportunities if you're not looking for traditional full-time employment or remote work. Source Lastly Here's A Github Profile Guide: Medium is causing strange formatting… they normally form a grid! ### Rubric: Discover More: Web-Dev-Hub Memoization, Tabulation, and Sorting Algorithms by Example Why is looking at runtime not a reliable method of… bgoonz-blog.netlify.app General How To Break Into Tech - Job Hunting and Interviews by Haseeb Qureshi Mintbean.io - Hackathons and Workshops Data on the job search and how to do it! LinkedIn Post Inspector LinkedIn Featured Images Frontend Masters - Expensive, but worth every penny Resume Spelling/Grammar mistakes on Resume costs jobs Cover Letter Six C's of Business Communication Heroku - Use at your own risk Keep Heroku App Awake For Free Using Google App Script UptimeRobot Kaffeine UptimeRobot and Dyno Lecture Trivia JavaScript Trivia Fullstack Cafe - EVERYTHING Front-end trivia Python Trivia Frontend Trivia 12 Essential Web Design Interview Questions Language Resources JavaScript Resources TypeScript Learning Plan React Native Code With Mosh Enrolled satagonia@gmail.com / qqqq1111 Python Resources- HTML5 Resources HTML5 Cheat Sheet HTML5 Rocks MDN - HTML MDN - HTML5 HTML5 Doctor- CSS3 Resources W3 Schools CSS3 Tutorial Tutorial Republic - Ultimate Tutorial for Beginners MDN - CSS CSS3.info CSS Tricks Complete Guide to Flexbox Complete Guide to Grid Interactive CSS Grid Generator CSS Zen Garden Flexbox Grid (Package) Specifishity CSS3 Cheat Sheet Jen Simmons Labs Miscellaneous Resources CodePen 2020 Most Popular Pens (replace year for more) Web Design Weekly Responsive Design Weekly DS&A Leetcode AlgoExpert Hash Tables: What is a Hash Table O(1) for a "good" table O(n) for a terrible table (lots of collisions, etc.) System Design The Basics Caching Load Balancing Interviewing Mock Interviewing Interviewing.io Networking MeetUp Managing and Organizing Job Search Notion Trillo clone but with added features that make it really great! Consider creating a template for new job seekers! Negotiations Haseeb's 10 Rules - Part 1 Haseeb's 10 Rules - Part 2 Portfolio Sites Take 25 minutes to choose a template, download it, rename it githubusername.github.io , git init, and push it to a github repo of the same name: Template Sources Free CSS Templates HTML5 UP Start Bootstrap Theme Wagon Templatemo One Page Love Once you've decided on a template, download it to your machine. Rename the folder {$yourGitHubUserName}.github.io, (e.g. if my GitHub username were QueenOfTheBeyhive, I would name my repo QueenOfTheBeyhive.github.io). This will be important for deployment to GitHub pages later. Make sure to git init and set up your remote repository. As always, make sure to read through any provided README for any potentially useful information. Take some time to explore the structure, included elements, and default assets included in the template. Take special note of style sheets and the main HTML file. The main HTML must be called index.html and it must be located in the root of the directory. If the file is located elsewhere, relocate it to the root and adjust any relative paths for any imported scripts or style sheets. QA Engineering Full course in 7 day trial Prep Notes Alternative Roles Data Analyst Sales Engineer Technical Support Engineer Customer Success Engineer Data Engineer Dev Ops Engineer QA Engineer Solutions Engineer Support Engineer Technical Product Manager Scrum Master Implementation Specialist Technical Account Manager Externship insidesherpa Open Source GitHub's open source guides Getting started with open source First timers only Open Source Underdogs Code Triage Volunteer Code For America Donate Code Social Coder Catch A Fire Hackers For Charity Imposter Syndrome The Imposter's Advantage - Zain Rizvi Stats on the tech giants Why MS degrees are shit Podcasts FreeCodeCamp Podcast Codish Podcast Books Grokking the Coding Interview GitHub Coding Questions Purchase Course Grokking the System Design Interview Quizzes Purchase Course Elements of Programming Interviews (EPI) in Python Amazon Skienna Algorithm Design Manual Amazon QA Questions 10:22:12 From Alexis Kozak to Everyone : Scenario 1 It's 7:00 pm on a Friday, and you receive a message from Dev Ops that they haven't been able to upgrade a live Production environment as planned. There were feature updates in this release that customers have planned marketing campaigns around. It also included a bug fix for one customer that's currently having to maintain a very manual workaround. What do you do? 10:24:40 From Alexis Kozak to Everyone : Scenario 2 An application has been configured to send an email every time a patient requests a changed email. The automated email sends something to the old email, acknowledging that they changed their email, and if that isn't right, to please contact Secular Health Network. When you come into the office one morning, you see that thousands of emails have been generated in the space of two hours. What do you do? How do you find the number of emails sent? 10:28:11 From Alexis Kozak to Everyone : Scenario 3 A customer has requested a change to SSO logic such that only users from a certain region can access SmartExam. You've implemented the rule on their demo environments and given them a testing plan that is simple and straightforward. During testing, you're included in multiple email chains with different parties, as well as some one-off calls and texts messages. Resources seem scattered, but the testing happens. After receiving confirmation from the customer that testing was successful, you're told the code is good to go into production. However, upon doing some quick checks, you discover that the rule you wrote doesn't work and would actually prevent any user from logging into SmartExam. The fix is quite simple. What do you do?
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Close Menu Youtube Back to top
    https://bgoonz-blog.netlify.app/images/code.png
  • Web-Dev-Hub
    Job Search Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet
    https://bgoonz-blog.netlify.app/images/code.png
  • Engineering Portfolio
    Engineering Portfolio Portfolio This is an embedded Microsoft Office presentation, powered by Office.
    https://bgoonz-blog.netlify.app/images/code.png